mirror of
https://github.com/boostorg/openmethod.git
synced 2026-01-20 16:52:12 +00:00
Compare commits
135 Commits
BOOST_REVI
...
boost-1.90
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83bc8d2c68 | ||
|
|
ba6d178f34 | ||
|
|
d59abed109 | ||
|
|
d5ccc9edaa | ||
|
|
d9edbe9607 | ||
|
|
3ef66b4b0f | ||
|
|
f7d47fbd35 | ||
|
|
e5762bd6e6 | ||
|
|
d057945a09 | ||
|
|
0bda0fee49 | ||
|
|
36d88320ba | ||
|
|
9fdc1274c1 | ||
|
|
8617f71a05 | ||
|
|
af52a803d6 | ||
|
|
b31bee24b2 | ||
|
|
e78199e8a0 | ||
|
|
a2d69a97d2 | ||
|
|
826188ec01 | ||
|
|
c9b682a679 | ||
|
|
6540e23971 | ||
|
|
4249f86bd7 | ||
|
|
19e0ff771b | ||
|
|
f259ee4c7e | ||
|
|
3392f1a636 | ||
|
|
81f4046b9b | ||
|
|
dc62c59f09 | ||
|
|
6c77104d9e | ||
|
|
c32fe5ef17 | ||
|
|
796eed633e | ||
|
|
386f6979b7 | ||
|
|
666e0c3da1 | ||
|
|
e6be4be05d | ||
|
|
eb0c5804f6 | ||
|
|
3ef25b2463 | ||
|
|
00abd9176b | ||
|
|
9ecf9158f9 | ||
|
|
c7bc263e81 | ||
|
|
f1819cd8b8 | ||
|
|
c9c0972edd | ||
|
|
fc17021a77 | ||
|
|
9ae95df2af | ||
|
|
98319c4797 | ||
|
|
36270d4d05 | ||
|
|
fa19da8c4b | ||
|
|
5dd55f2141 | ||
|
|
838dc1d261 | ||
|
|
e3c76f07f7 | ||
|
|
40350dd854 | ||
|
|
68fc3f56ad | ||
|
|
397ccb6dde | ||
|
|
4ecde2e91d | ||
|
|
efbc135a59 | ||
|
|
830c3ce71c | ||
|
|
c4f967f025 | ||
|
|
626c74960a | ||
|
|
1b94d2948e | ||
|
|
9a04e30506 | ||
|
|
6433a6791b | ||
|
|
41c462986b | ||
|
|
b41f40f1d1 | ||
|
|
adc15fcd53 | ||
|
|
8595067b5c | ||
|
|
5a6670fcf6 | ||
|
|
627f3c1c0e | ||
|
|
4b80801c97 | ||
|
|
4fceb9a6fa | ||
|
|
5c3187816d | ||
|
|
0b71a75a47 | ||
|
|
e309695f61 | ||
|
|
7d5557fb18 | ||
|
|
1c0e69b94c | ||
|
|
0fdca389a8 | ||
|
|
f6172e4262 | ||
|
|
3bec1ee519 | ||
|
|
b905379285 | ||
|
|
1cf37e79b5 | ||
|
|
f36ac792cf | ||
|
|
81690dca4a | ||
|
|
4b3bc74de2 | ||
|
|
a22089f597 | ||
|
|
bfa003e42c | ||
|
|
34ebad0e90 | ||
|
|
d21dcb0b52 | ||
|
|
45a5769238 | ||
|
|
f58d92bf94 | ||
|
|
aa15a7ab5d | ||
|
|
b179cce168 | ||
|
|
11b43d2472 | ||
|
|
0545d7e8ea | ||
|
|
31b48568cb | ||
|
|
baff0d3f23 | ||
|
|
0416b9b888 | ||
|
|
6a9ccf170b | ||
|
|
489f1d27d8 | ||
|
|
83c8ab9afd | ||
|
|
44475ab117 | ||
|
|
bfa9c01b3d | ||
|
|
0038f21569 | ||
|
|
4a9b9e439d | ||
|
|
88832cc96c | ||
|
|
8e439f2934 | ||
|
|
1c971c5fc9 | ||
|
|
a078c9c002 | ||
|
|
9edce6902b | ||
|
|
38140e57ae | ||
|
|
d352a55d58 | ||
|
|
a0720ca8b6 | ||
|
|
e1658db6d1 | ||
|
|
22fc7e8fd7 | ||
|
|
ac1e0efb1c | ||
|
|
c1f3f603ca | ||
|
|
5c1dfd8c64 | ||
|
|
5a58be1aa8 | ||
|
|
8ec027c55a | ||
|
|
e92a241c73 | ||
|
|
97766ef47a | ||
|
|
179967f9c2 | ||
|
|
ae60941daf | ||
|
|
e8c57b44ff | ||
|
|
ded8ceabfa | ||
|
|
efc8cbff52 | ||
|
|
2f9734b403 | ||
|
|
e26798bd2f | ||
|
|
a64bd54c18 | ||
|
|
186bf508c2 | ||
|
|
9571fefb17 | ||
|
|
1c8bbd22d2 | ||
|
|
921fb312d5 | ||
|
|
da937900d9 | ||
|
|
e80d443dbf | ||
|
|
dba92d1d39 | ||
|
|
0b44fc5973 | ||
|
|
40c90777aa | ||
|
|
e8ec2611cb | ||
|
|
93e0388ab1 |
23
.codecov.yml
Normal file
23
.codecov.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
# Copyright 2019 - 2021 Alexander Grund
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Sample codecov configuration file. Edit as required
|
||||
|
||||
codecov:
|
||||
max_report_age: off
|
||||
require_ci_to_pass: yes
|
||||
notify:
|
||||
# Increase this if you have multiple coverage collection jobs
|
||||
after_n_builds: 1
|
||||
wait_for_ci: yes
|
||||
|
||||
# Change how pull request comments look
|
||||
comment:
|
||||
layout: "reach,diff,flags,files,footer"
|
||||
|
||||
# Ignore specific files or folders. Glob patterns are supported.
|
||||
# See https://docs.codecov.com/docs/ignoring-paths
|
||||
ignore:
|
||||
- extra/**/*
|
||||
# - test/**/*
|
||||
354
.drone.jsonnet
Normal file
354
.drone.jsonnet
Normal file
@@ -0,0 +1,354 @@
|
||||
# Copyright 2022 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
local library = "openmethod";
|
||||
|
||||
local triggers =
|
||||
{
|
||||
branch: [ "master", "develop", "feature/*", "fix/*" ]
|
||||
};
|
||||
|
||||
local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' };
|
||||
local asan = { ASAN: '1' };
|
||||
|
||||
local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "docker",
|
||||
trigger: triggers,
|
||||
platform:
|
||||
{
|
||||
os: "linux",
|
||||
arch: arch
|
||||
},
|
||||
steps:
|
||||
[
|
||||
{
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'set -e',
|
||||
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
|
||||
] +
|
||||
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
|
||||
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
|
||||
[
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "exec",
|
||||
trigger: triggers,
|
||||
platform: {
|
||||
"os": "darwin",
|
||||
"arch": arch
|
||||
},
|
||||
node: {
|
||||
"os": osx_version
|
||||
},
|
||||
steps: [
|
||||
{
|
||||
name: "everything",
|
||||
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
|
||||
commands:
|
||||
[
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "docker",
|
||||
trigger: triggers,
|
||||
platform:
|
||||
{
|
||||
os: "windows",
|
||||
arch: arch
|
||||
},
|
||||
"steps":
|
||||
[
|
||||
{
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'cmd /C .drone\\\\drone.bat ' + library,
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
[
|
||||
linux_pipeline(
|
||||
"Linux 18.04 GCC 8 32/64",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '17', ADDRMD: '32,64' },
|
||||
"g++-8-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* 32/64",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '17,2a', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* ARM64",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '17,2a' },
|
||||
arch="arm64",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* S390x",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '17,2a' },
|
||||
arch="s390x",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 10 32/64",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '17,20', ADDRMD: '32,64' },
|
||||
"g++-10-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 GCC 11* 32/64",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '17,2a', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 GCC 12 32/64 C++11-14",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '17,20', ADDRMD: '32,64' },
|
||||
"g++-12-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 GCC 12 32/64 C++17-20",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '2b', ADDRMD: '32,64' },
|
||||
"g++-12-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 13 32/64 UBSAN C++17-20",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '17,20', ADDRMD: '32,64' } + ubsan,
|
||||
"g++-13-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 13 32/64 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '2b', ADDRMD: '32,64' } + ubsan,
|
||||
"g++-13-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 13 32 ASAN C++17-20",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '17,20', ADDRMD: '32' } + asan,
|
||||
"g++-13-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 13 32 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '2b', ADDRMD: '32' } + asan,
|
||||
"g++-13-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 UBSAN C++17",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '17' } + ubsan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 UBSAN C++20",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '20' } + ubsan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '2b' } + ubsan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 ASAN C++17",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '17' } + asan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 ASAN C++20",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '20' } + asan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '2b' } + asan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 7",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-7', CXXSTD: '17' },
|
||||
"clang-7",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 8",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-8', CXXSTD: '17' },
|
||||
"clang-8",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 9",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-9', CXXSTD: '17,2a' },
|
||||
"clang-9",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 10",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-10', CXXSTD: '17,2a' },
|
||||
"clang-10",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 11",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-11', CXXSTD: '17,2a' },
|
||||
"clang-11",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 Clang 12",
|
||||
"cppalliance/droneubuntu2004:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-12', CXXSTD: '17,2a' },
|
||||
"clang-12",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 Clang 13",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '17,20' },
|
||||
"clang-13",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 Clang 14",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '17,20,2b' },
|
||||
"clang-14",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 Clang 15",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '17,20,2b' },
|
||||
"clang-15",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 16",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '17,20,2b' },
|
||||
"clang-16",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 17 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '17,20,2b' } + ubsan,
|
||||
"clang-17",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 17 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '17,20,2b' } + asan,
|
||||
"clang-17",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 18 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '17,20,2b' } + ubsan,
|
||||
"clang-18",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 18 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '17,20,2b' } + asan,
|
||||
"clang-18",
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '17,2a' } + ubsan,
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 ASAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '17,2a' } + asan,
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 12.4 Xcode 13.4.1 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '17,20,2b', LINK: 'static' } + ubsan,
|
||||
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 12.4 Xcode 13.4.1 ASAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '17,20,2b' } + asan,
|
||||
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2019 msvc-14.2",
|
||||
"cppalliance/dronevs2019",
|
||||
{ TOOLSET: 'msvc-14.2', CXXSTD: '17,20,latest', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2022 msvc-14.3",
|
||||
"cppalliance/dronevs2022:1",
|
||||
{ TOOLSET: 'msvc-14.3', CXXSTD: '17,20,latest', ADDRMD: '32,64' },
|
||||
),
|
||||
]
|
||||
24
.drone/drone.bat
Normal file
24
.drone/drone.bat
Normal file
@@ -0,0 +1,24 @@
|
||||
@REM Copyright 2022 Peter Dimov
|
||||
@REM Distributed under the Boost Software License, Version 1.0.
|
||||
@REM https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@ECHO ON
|
||||
|
||||
set LIBRARY=%1
|
||||
set DRONE_BUILD_DIR=%CD%
|
||||
|
||||
set BOOST_BRANCH=develop
|
||||
if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
git submodule update --init tools/boostdep
|
||||
mkdir -p libs\%LIBRARY% & REM remove when/if the library makes it into Boost
|
||||
xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\
|
||||
python tools/boostdep/depinst/depinst.py -I examples %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
|
||||
26
.drone/drone.sh
Executable file
26
.drone/drone.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2022 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
set -ex
|
||||
export PATH=~/.local/bin:/usr/local/bin:$PATH
|
||||
|
||||
DRONE_BUILD_DIR=$(pwd)
|
||||
|
||||
BOOST_BRANCH=develop
|
||||
if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
|
||||
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
mkdir -p libs/$LIBRARY # remove when/if the library makes it into Boost
|
||||
git submodule update --init tools/boostdep
|
||||
cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY
|
||||
python tools/boostdep/depinst/depinst.py -I examples $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
./b2 -j3 libs/$LIBRARY/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} ${LINK:+link=$LINK}
|
||||
127
.github/workflows/ci.yml
vendored
Normal file
127
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
#
|
||||
# Copyright 2020-2021 Peter Dimov
|
||||
# Copyright 2021 Andrey Semashev
|
||||
# Copyright 2021-2024 Alexander Grund
|
||||
# Copyright 2022-2025 James E. King III
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# This workflow uses the Boost.CI reusable workflow which builds a variety of
|
||||
# configurations of your project, runs tests, and generates code coverage reports.
|
||||
#
|
||||
# To use it, copy this file into your repository as `.github/workflows/ci.yml` and
|
||||
# customize it appropriately.
|
||||
#
|
||||
---
|
||||
name: Boost.CI
|
||||
|
||||
permissions:
|
||||
id-token: write
|
||||
pages: write
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- bugfix/**
|
||||
- feature/**
|
||||
- fix/**
|
||||
- github/**
|
||||
- pr/**
|
||||
paths-ignore:
|
||||
- LICENSE
|
||||
- meta/**
|
||||
# - README.md
|
||||
|
||||
jobs:
|
||||
call-boost-ci:
|
||||
name: Run Boost.CI
|
||||
uses: boostorg/boost-ci/.github/workflows/reusable.yml@master
|
||||
with:
|
||||
exclude_cxxstd: '98,03,0x,11,14'
|
||||
exclude_compiler: gcc-4.9,gcc-5,gcc-6,gcc-7,clang-3.9,clang-4.0,clang-5.0,clang-6.0,clang-7,clang-16
|
||||
# exclude clang-16 because it seems to use the c++14 standard library on ubuntu-24.04:
|
||||
# include/c++/14/bits/stl_pair.h:410:35: error: no matching function for call to 'get'
|
||||
# maybe similar to this: https://github.com/actions/runner-images/issues/9679
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }}
|
||||
COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||
|
||||
antora:
|
||||
name: Antora docs
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- { name: Windows, os: windows-latest }
|
||||
- { name: Ubuntu, os: ubuntu-latest }
|
||||
- { name: macOS, os: macos-15 }
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- name: Install packages
|
||||
uses: alandefreitas/cpp-actions/package-install@v1.8.8
|
||||
with:
|
||||
apt-get: git cmake
|
||||
|
||||
- name: Clone Boost.OpenMethod
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Clone Boost
|
||||
uses: alandefreitas/cpp-actions/boost-clone@v1.8.8
|
||||
id: boost-clone
|
||||
with:
|
||||
branch: ${{ (github.ref_name == 'master' && github.ref_name) || 'develop' }}
|
||||
boost-dir: ../boost-source
|
||||
scan-modules-dir: .
|
||||
scan-modules-ignore: openmethod
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Setup Ninja
|
||||
if: runner.os == 'Windows'
|
||||
uses: seanmiddleditch/gha-setup-ninja@v5
|
||||
|
||||
- name: Build Antora docs
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
git config --global --add safe.directory "$(pwd)"
|
||||
|
||||
cd ..
|
||||
BOOST_SRC_DIR="$(pwd)/boost-source"
|
||||
export BOOST_SRC_DIR
|
||||
|
||||
cd openmethod
|
||||
cd doc
|
||||
bash ./build_antora.sh
|
||||
|
||||
# Antora returns zero even if it fails, so we check if the site directory exists.
|
||||
if [ ! -d "html" ]
|
||||
then
|
||||
echo "Antora build failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create Antora docs artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: antora-docs-${{ matrix.name }}
|
||||
path: doc/html
|
||||
|
||||
- name: Upload static files as artifact
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: doc/html
|
||||
|
||||
- name: Deploy to GitHub Pages (jll63)
|
||||
if: matrix.os == 'ubuntu-latest' && github.repository_owner == 'jll63' && github.ref_name == 'feature/doc'
|
||||
uses: actions/deploy-pages@v4
|
||||
123
.github/workflows/main.yml
vendored
123
.github/workflows/main.yml
vendored
@@ -1,123 +0,0 @@
|
||||
# Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt
|
||||
# or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# CI is quite simple at the moment. It will be improved and made more
|
||||
# comprehensive, probably similar to Boost.Unordered.
|
||||
|
||||
name: CI
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Debug Release
|
||||
|
||||
permissions:
|
||||
contents: 'read'
|
||||
pages: 'write'
|
||||
id-token: 'write'
|
||||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
Ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config: [Debug, Release]
|
||||
compiler: [clang++, g++]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install clang++
|
||||
run: |
|
||||
wget https://apt.llvm.org/llvm.sh
|
||||
chmod +x llvm.sh
|
||||
sudo ./llvm.sh $1
|
||||
if: matrix.compiler == 'clang++'
|
||||
- name: Install Boost
|
||||
run: sudo apt-get install -y libboost-all-dev
|
||||
- name: Configure
|
||||
run: cmake -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DBUILD_TESTING=1 -DBUILD_EXAMPLES=1 -Bbuild
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
- name: Test
|
||||
run: |
|
||||
ctest --test-dir build --rerun-failed --output-on-failure
|
||||
Windows:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config: [Debug, Release]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: Install boost
|
||||
uses: MarkusJx/install-boost@v2
|
||||
id: install-boost
|
||||
with:
|
||||
boost_version: 1.87.0
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DBUILD_TESTING=1 -DBUILD_EXAMPLES=1 -Bbuild -DBoost_DIR=${{ steps.install-boost.outputs.BOOST_ROOT }} -DBoost_INCLUDE_DIR=${{steps.install-boost.outputs.BOOST_ROOT}}\include -DBoost_LIBRARY_DIRS=${{steps.install-boost.outputs.BOOST_ROOT}}\lib
|
||||
env:
|
||||
BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }}
|
||||
- name: Build
|
||||
run: cmake --build build --config ${{ matrix.config }}
|
||||
- name: Test
|
||||
run: |
|
||||
ctest --test-dir build --rerun-failed --output-on-failure -C ${{ matrix.config }}
|
||||
MacOS:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config: [Debug, Release]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: Install boost
|
||||
run: brew install boost
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DBUILD_TESTING=1 -DBUILD_EXAMPLES=1 -Bbuild
|
||||
- name: Build
|
||||
run: |
|
||||
cmake --build build
|
||||
- name: Test
|
||||
run: |
|
||||
ctest --test-dir build --rerun-failed --output-on-failure
|
||||
Artifacts:
|
||||
if: github.ref_name == 'master'
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install asciidoctor
|
||||
run: |
|
||||
sudo apt-get install asciidoctor
|
||||
asciidoctor doc/openmethod.adoc -o build_outputs_folder/index.html
|
||||
- name: Generate documentation
|
||||
run: |
|
||||
sudo apt-get install asciidoctor
|
||||
asciidoctor doc/openmethod.adoc -o build_outputs_folder/index.html
|
||||
- name: Build flat headers
|
||||
run: |
|
||||
mkdir -p build_outputs_folder/boost/openmethod
|
||||
python3 dev/flatten.py \
|
||||
build_outputs_folder/boost/openmethod.hpp \
|
||||
include/boost/openmethod.hpp \
|
||||
include/boost/openmethod/unique_ptr.hpp \
|
||||
include/boost/openmethod/shared_ptr.hpp \
|
||||
include/boost/openmethod/compiler.hpp
|
||||
python3 dev/flatten.py \
|
||||
build_outputs_folder/boost/openmethod/policies.hpp \
|
||||
include/boost/openmethod/policies.hpp
|
||||
- name: Upload static files as artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: build_outputs_folder/
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: actions/deploy-pages@v4
|
||||
15
.github/workflows/probe.yml
vendored
15
.github/workflows/probe.yml
vendored
@@ -1,15 +0,0 @@
|
||||
name: Probe Workflow
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
probe:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: List available compilers
|
||||
run: |
|
||||
lsb_release -a
|
||||
apt list --installed | grep clang
|
||||
apt list --installed | grep g++
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,6 +4,7 @@ build/
|
||||
builds/
|
||||
**/#*#
|
||||
dependencies/*
|
||||
Dependencies/*
|
||||
extern/*
|
||||
tests/benchmarks_parameters.hpp
|
||||
**/vcpkg_installed
|
||||
@@ -26,3 +27,4 @@ fetch_and_include/
|
||||
tmpinst/
|
||||
|
||||
CMakeFiles/
|
||||
build/
|
||||
|
||||
217
CMakeLists.txt
217
CMakeLists.txt
@@ -1,49 +1,194 @@
|
||||
# Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt
|
||||
# or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
# Copyright (c) 2021 DMitry Arkhipov (grisumbras@gmail.com)
|
||||
# Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Official repository: https://github.com/boostorg/openmethod
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
if(POLICY CMP0167)
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
cmake_minimum_required(VERSION 3.8...3.20)
|
||||
|
||||
set(BOOST_OPENMETHOD_VERSION 1)
|
||||
|
||||
if (BOOST_SUPERPROJECT_VERSION)
|
||||
set(BOOST_OPENMETHOD_VERSION ${BOOST_SUPERPROJECT_VERSION})
|
||||
endif ()
|
||||
|
||||
project(boost_openmethod VERSION "${BOOST_OPENMETHOD_VERSION}" LANGUAGES CXX)
|
||||
|
||||
set(BOOST_OPENMETHOD_IS_ROOT OFF)
|
||||
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(BOOST_OPENMETHOD_IS_ROOT ON)
|
||||
endif ()
|
||||
set(__ignore__ ${CMAKE_C_COMPILER})
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Options
|
||||
#
|
||||
#-------------------------------------------------
|
||||
option(BOOST_OPENMETHOD_BUILD_TESTS "Build boost::openmethod tests even if BUILD_TESTING is OFF" OFF)
|
||||
option(BOOST_OPENMETHOD_BUILD_EXAMPLES "Build boost::openmethod examples" ${BOOST_OPENMETHOD_IS_ROOT})
|
||||
option(BOOST_OPENMETHOD_MRDOCS_BUILD "Build the target for MrDocs: see mrdocs.yml" OFF)
|
||||
option(BOOST_OPENMETHOD_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF)
|
||||
|
||||
# Check if environment variable BOOST_SRC_DIR is set
|
||||
if (NOT DEFINED BOOST_SRC_DIR AND DEFINED ENV{BOOST_SRC_DIR})
|
||||
set(DEFAULT_BOOST_SRC_DIR "$ENV{BOOST_SRC_DIR}")
|
||||
else ()
|
||||
set(DEFAULT_BOOST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..")
|
||||
endif ()
|
||||
set(BOOST_SRC_DIR ${DEFAULT_BOOST_SRC_DIR} CACHE STRING "Boost source dir to use when running CMake from this directory")
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Boost modules
|
||||
#
|
||||
#-------------------------------------------------
|
||||
# The boost super-project requires one explicit dependency per-line.
|
||||
|
||||
set(
|
||||
BOOST_OPENMETHOD_DEPENDENCIES
|
||||
Boost::assert
|
||||
Boost::config
|
||||
Boost::core
|
||||
Boost::dynamic_bitset
|
||||
Boost::mp11
|
||||
Boost::preprocessor
|
||||
)
|
||||
|
||||
|
||||
foreach (BOOST_OPENMETHOD_DEPENDENCY ${BOOST_OPENMETHOD_DEPENDENCIES})
|
||||
if (BOOST_OPENMETHOD_DEPENDENCY MATCHES "^[ ]*Boost::([A-Za-z0-9_]+)[ ]*$")
|
||||
list(APPEND BOOST_OPENMETHOD_INCLUDE_LIBRARIES ${CMAKE_MATCH_1})
|
||||
endif ()
|
||||
endforeach ()
|
||||
# Conditional dependencies
|
||||
if (NOT BOOST_OPENMETHOD_MRDOCS_BUILD)
|
||||
if (BUILD_TESTING OR BOOST_OPENMETHOD_BUILD_TESTS)
|
||||
set(BOOST_OPENMETHOD_UNIT_TEST_LIBRARIES test)
|
||||
endif()
|
||||
if (BOOST_OPENMETHOD_BUILD_EXAMPLES)
|
||||
set(BOOST_OPENMETHOD_EXAMPLE_LIBRARIES dll)
|
||||
endif()
|
||||
endif()
|
||||
# Complete dependency list
|
||||
set(BOOST_INCLUDE_LIBRARIES ${BOOST_OPENMETHOD_INCLUDE_LIBRARIES} ${BOOST_OPENMETHOD_UNIT_TEST_LIBRARIES} ${BOOST_OPENMETHOD_EXAMPLE_LIBRARIES})
|
||||
set(BOOST_EXCLUDE_LIBRARIES openmethod)
|
||||
|
||||
if(POLICY CMP0167)
|
||||
cmake_policy(SET CMP0167 NEW)
|
||||
endif()
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Add Boost Subdirectory
|
||||
#
|
||||
#-------------------------------------------------
|
||||
if (BOOST_OPENMETHOD_IS_ROOT)
|
||||
set(CMAKE_FOLDER Dependencies)
|
||||
# Find absolute BOOST_SRC_DIR
|
||||
if (NOT IS_ABSOLUTE ${BOOST_SRC_DIR})
|
||||
set(BOOST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${BOOST_SRC_DIR}")
|
||||
endif ()
|
||||
|
||||
project(boost_openmethod VERSION 1.87.0 LANGUAGES CXX)
|
||||
# Validate BOOST_SRC_DIR
|
||||
set(BOOST_SRC_DIR_IS_VALID ON)
|
||||
foreach (F "CMakeLists.txt" "Jamroot" "boost-build.jam" "bootstrap.sh" "libs")
|
||||
if (NOT EXISTS "${BOOST_SRC_DIR}/${F}")
|
||||
message(STATUS "${BOOST_SRC_DIR}/${F} does not exist. Fallback to find_package.")
|
||||
set(BOOST_SRC_DIR_IS_VALID OFF)
|
||||
break()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
# Create Boost interface targets
|
||||
if (BOOST_SRC_DIR_IS_VALID)
|
||||
# From BOOST_SRC_DIR
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
endif()
|
||||
set(BOOST_EXCLUDE_LIBRARIES ${PROJECT_NAME})
|
||||
set(PREV_BUILD_TESTING ${BUILD_TESTING})
|
||||
set(BUILD_TESTING OFF CACHE BOOL "Build the tests." FORCE)
|
||||
add_subdirectory(${BOOST_SRC_DIR} Dependencies/boost EXCLUDE_FROM_ALL)
|
||||
set(BUILD_TESTING ${PREV_BUILD_TESTING} CACHE BOOL "Build the tests." FORCE)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${BOOST_SRC_DIR}/tools/cmake/include")
|
||||
else ()
|
||||
# From Boost Package
|
||||
find_package(Boost REQUIRED COMPONENTS container)
|
||||
foreach (BOOST_INCLUDE_LIBRARY ${BOOST_INCLUDE_LIBRARIES})
|
||||
if (NOT TARGET Boost::${BOOST_INCLUDE_LIBRARY})
|
||||
add_library(Boost::${BOOST_INCLUDE_LIBRARY} ALIAS Boost::headers)
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
unset(CMAKE_FOLDER)
|
||||
endif ()
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Library
|
||||
#
|
||||
#-------------------------------------------------
|
||||
file(GLOB_RECURSE BOOST_OPENMETHOD_HEADERS CONFIGURE_DEPENDS include/boost/*.hpp)
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/include/boost PREFIX "" FILES ${BOOST_OPENMETHOD_HEADERS})
|
||||
|
||||
function(boost_openmethod_setup_properties target)
|
||||
target_link_libraries(${target} INTERFACE ${BOOST_OPENMETHOD_DEPENDENCIES})
|
||||
endfunction()
|
||||
|
||||
add_library(boost_openmethod INTERFACE)
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19)
|
||||
target_sources(boost_openmethod PRIVATE ${BOOST_OPENMETHOD_HEADERS})
|
||||
endif()
|
||||
|
||||
add_library(Boost::openmethod ALIAS boost_openmethod)
|
||||
target_include_directories(boost_openmethod INTERFACE "${PROJECT_SOURCE_DIR}/include")
|
||||
boost_openmethod_setup_properties(boost_openmethod)
|
||||
target_compile_features(boost_openmethod INTERFACE cxx_std_17)
|
||||
|
||||
target_include_directories(boost_openmethod INTERFACE include)
|
||||
|
||||
find_package(Boost COMPONENTS)
|
||||
target_link_libraries(boost_openmethod INTERFACE Boost::boost)
|
||||
|
||||
if(MSVC)
|
||||
add_compile_options(/EHsc /FAs)
|
||||
if (BOOST_OPENMETHOD_MRDOCS_BUILD)
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/mrdocs.cpp" "#include <boost/openmethod.hpp>\n")
|
||||
foreach (HEADER ${BOOST_OPENMETHOD_HEADERS})
|
||||
string(REPLACE "${PROJECT_SOURCE_DIR}/include/" "" HEADER "${HEADER}")
|
||||
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/mrdocs.cpp" "#include <${HEADER}>\n")
|
||||
endforeach()
|
||||
add_library(boost_openmethod_mrdocs "${CMAKE_CURRENT_BINARY_DIR}/mrdocs.cpp")
|
||||
target_include_directories(boost_openmethod_mrdocs PUBLIC "${PROJECT_SOURCE_DIR}/include")
|
||||
boost_openmethod_setup_properties(boost_openmethod_mrdocs)
|
||||
target_link_libraries(boost_openmethod_mrdocs PUBLIC Boost::openmethod)
|
||||
target_compile_definitions(boost_openmethod_mrdocs PUBLIC BOOST_OPENMETHOD_MRDOCS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(GCC)
|
||||
add_compile_options(-fPIC -fvisibility=hidden -Wno-deprecated-declarations -Wall -Wextra)
|
||||
endif()
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Tests
|
||||
#
|
||||
#-------------------------------------------------
|
||||
if (BUILD_TESTING OR BOOST_OPENMETHOD_BUILD_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
if (BOOST_OPENMETHOD_IS_ROOT)
|
||||
add_custom_target(all_with_tests ALL DEPENDS tests)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
message(STATUS "Building tests")
|
||||
include(CTest)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
if(BUILD_EXAMPLES)
|
||||
message(STATUS "Building examples")
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
#-------------------------------------------------
|
||||
if (BOOST_OPENMETHOD_BUILD_EXAMPLES)
|
||||
enable_testing()
|
||||
add_subdirectory(doc/modules/ROOT/examples)
|
||||
endif ()
|
||||
|
||||
39
README.md
39
README.md
@@ -1,16 +1,31 @@
|
||||
# Boost.OpenMethod
|
||||
### License
|
||||
|
||||
THIS IS NOT A BOOST LIBRARY (yet).
|
||||
Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
|
||||
|
||||
The content of this repository is derived from YOMM2. It has been adapted to
|
||||
Boost naming conventions for the purpose of being reviewed for inclusion in the
|
||||
Boost C++ libraries.
|
||||
### Properties
|
||||
|
||||
The documentation is [here](https://jll63.github.io/Boost.OpenMethod/).
|
||||
* C++17
|
||||
* Header-Only
|
||||
|
||||
You can experiment with the library on Compiler Explorer by including
|
||||
`<https://jll63.github.io/Boost.OpenMethod/boost/openmethod.hpp>`. It also
|
||||
includes the headers for the compiler, `shared_ptr` and `unique_ptr`. For
|
||||
example, here is the last iteration of the [AST
|
||||
example](https://godbolt.org/z/cPjzfanc8) from the tutorial. Don't forget to
|
||||
turn on optimizations (`-O2 -DNDEBUG`) and to select the Boost library.
|
||||
### Build Status
|
||||
|
||||
Branch | GH Actions | Coverity Scan | codecov.io | Deps | Docs | Tests |
|
||||
:-------------: | ---------- | -------------- | ---------- | ---- | ---- | ----- |
|
||||
[`master`](https://github.com/jll63/openmethod/tree/master) | [](https://github.com/jll63/openmethod/actions/workflows/ci.yml) | [](https://scan.coverity.com/projects/boostorg-openmethod) | [](https://codecov.io/gh/jll63/openmethod/branch/master) | [](https://pdimov.github.io/boostdep-report/master/openmethod.html) | [](https://www.boost.org/doc/libs/master/libs/openmethod/doc/html/openmethod.html) | [](http://www.boost.org/development/tests/master/developer/openmethod.html)
|
||||
[`develop`](https://github.com/jll63/openmethod/tree/develop) | [](https://github.com/jll63/openmethod/actions/workflows/ci.yml) | [](https://scan.coverity.com/projects/boostorg-openmethod) | [](https://codecov.io/gh/jll63/openmethod/branch/develop) | [](https://pdimov.github.io/boostdep-report/develop/openmethod.html) | [](https://www.boost.org/doc/libs/develop/libs/openmethod/doc/html/openmethod.html) | [](http://www.boost.org/development/tests/develop/developer/openmethod.html)
|
||||
|
||||
### Directories
|
||||
|
||||
| Name | Purpose |
|
||||
| ----------- | ------------------------------ |
|
||||
| `doc` | documentation |
|
||||
| `example` | examples |
|
||||
| `include` | headers |
|
||||
| `test` | unit tests |
|
||||
|
||||
### More information
|
||||
|
||||
* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-openmethod)
|
||||
* [Report bugs](https://github.com/jll63/openmethod/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
|
||||
* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
|
||||
* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[openmethod]` tag at the beginning of the subject line.
|
||||
|
||||
@@ -13,14 +13,14 @@ constant boost_dependencies
|
||||
/boost/preprocessor//boost_preprocessor
|
||||
;
|
||||
|
||||
project /boost/open_method ;
|
||||
project /boost/openmethod ;
|
||||
|
||||
alias boost_open_method
|
||||
alias boost_openmethod
|
||||
: usage-requirements
|
||||
<include>include
|
||||
<library>$(boost_dependencies)
|
||||
;
|
||||
alias all : boost_open_method test ;
|
||||
alias all : boost_openmethod test ;
|
||||
explicit all ;
|
||||
|
||||
call-if : boost-library open_method ;
|
||||
call-if : boost-library openmethod ;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
struct Animal {
|
||||
const char* name;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
struct Animal {
|
||||
const char* name;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
struct Animal {
|
||||
const char* name;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
struct Animal {
|
||||
const char* name;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
struct Animal {
|
||||
const char* name;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
struct Animal {
|
||||
const char* name;
|
||||
|
||||
@@ -5,19 +5,20 @@ from pathlib import Path
|
||||
import re
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('output', type=Path)
|
||||
parser.add_argument('input', nargs="+", type=Path)
|
||||
parser.add_argument("output", type=Path)
|
||||
parser.add_argument("input", nargs="+", type=Path)
|
||||
args = parser.parse_args()
|
||||
|
||||
prefix = args.input[0].absolute()
|
||||
|
||||
while prefix.name != 'boost':
|
||||
while prefix.name != "boost":
|
||||
assert prefix.parent != prefix
|
||||
prefix = prefix.parent
|
||||
|
||||
prefix = prefix.parent
|
||||
skip = len(str(prefix)) + 1
|
||||
|
||||
|
||||
def flatten(input, output, done):
|
||||
header = str(input)[skip:]
|
||||
if header in done:
|
||||
@@ -25,16 +26,22 @@ def flatten(input, output, done):
|
||||
done.add(header)
|
||||
with input.open() as ifh:
|
||||
for line in ifh:
|
||||
if input.name != "openmethod.hpp" and re.match(
|
||||
r"#include <(boost/openmethod/core\.hpp+)>", line
|
||||
):
|
||||
continue
|
||||
|
||||
if m := re.match(r"#include <(boost/openmethod/[^>]+)>", line):
|
||||
include = m[1]
|
||||
print(file=output)
|
||||
flatten(prefix / include, output, done)
|
||||
print(file=output)
|
||||
else:
|
||||
output.write(line)
|
||||
continue
|
||||
|
||||
output.write(line)
|
||||
|
||||
|
||||
with args.output.open('w') as ofh:
|
||||
with args.output.open("w") as ofh:
|
||||
done = set()
|
||||
for input in args.input:
|
||||
flatten(input.absolute(), ofh, done)
|
||||
|
||||
11
dev/flatten.sh
Executable file
11
dev/flatten.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
mkdir -p build_outputs_folder/boost/openmethod
|
||||
|
||||
python3 dev/flatten.py build_outputs_folder/boost/openmethod.hpp \
|
||||
include/boost/openmethod.hpp
|
||||
|
||||
for header in core compiler shared_ptr unique_ptr; do
|
||||
python3 dev/flatten.py "build_outputs_folder/boost/openmethod/$header.hpp" \
|
||||
"include/boost/openmethod/$header.hpp"
|
||||
done
|
||||
12
dev/local-flat.sh
Executable file
12
dev/local-flat.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
mkdir -p flat/boost/openmethod
|
||||
python3 dev/flatten.py \
|
||||
flat/boost/openmethod.hpp \
|
||||
include/boost/openmethod.hpp \
|
||||
include/boost/openmethod/interop/std_unique_ptr.hpp \
|
||||
include/boost/openmethod/interop/std_shared_ptr.hpp \
|
||||
include/boost/openmethod/initialize.hpp
|
||||
python3 dev/flatten.py \
|
||||
flat/boost/openmethod/registry.hpp \
|
||||
include/boost/openmethod/registry.hpp \
|
||||
include/boost/openmethod/policies/*.hpp \
|
||||
include/boost/openmethod/default_registry.hpp
|
||||
6
doc/.gitignore
vendored
Normal file
6
doc/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
temp
|
||||
out.txt
|
||||
qbk/reference.qbk
|
||||
node_modules
|
||||
build
|
||||
reference-output
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
[#BOOST_OPENMETHOD]
|
||||
|
||||
## BOOST_OPENMETHOD
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD(NAME, (PARAMETERS...), RETURN_TYPE [, POLICY]);
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
Declares a method.
|
||||
|
||||
The macro expands to several constructs:
|
||||
|
||||
* A `struct` forward declaration that acts as the method's identifier:
|
||||
|
||||
```c++
|
||||
struct BOOST_OPENMETHOD_NAME(NAME);
|
||||
```
|
||||
|
||||
* An inline function template, constrained to take the same `PARAMETERS`,
|
||||
without the `virtual_` decorators, returning a `RETURN_TYPE`. The function
|
||||
forwards to +
|
||||
`method<BOOST_OPENMETHOD_NAME(NAME)(PARAMETERS...), RETURN_TYPE, POLICY>::fn`.
|
||||
|
||||
* A guide function used to match overriders with the method:
|
||||
|
||||
```c++
|
||||
auto BOOST_OPENMETHOD_NAME(NAME)_guide(...)
|
||||
-> ::boost::openmethod::method<
|
||||
BOOST_OPENMETHOD_NAME(NAME)(PARAMETERS...), RETURN_TYPE [, POLICY]>;
|
||||
```
|
||||
|
||||
NOTE: `NAME` must be an *identifier*. Qualified names are not allowed.
|
||||
|
||||
NOTE: The default value for `POLICY` is the value of
|
||||
`BOOST_OPENMETHOD_DEFAULT_POLICY` at the point `<boost/openmethod/core.hpp>` is
|
||||
included. Changing the value of this symbol has no effect after that point.
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
[#BOOST_OPENMETHOD_CLASSES]
|
||||
|
||||
## BOOST_OPENMETHOD_CLASSES
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD_CLASSES(CLASSES...[, POLICY]);
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
Register `CLASSES` in POLICY.
|
||||
|
||||
NOTE: The default value for `POLICY` is the value of
|
||||
`BOOST_OPENMETHOD_DEFAULT_POLICY` when `<boost/openmethod/core.hpp>` is
|
||||
included. Subsequently changing it has no retroactive effect.
|
||||
|
||||
This macro is a wrapper around `use_classes`; see its documentation for more
|
||||
details.
|
||||
@@ -1,52 +0,0 @@
|
||||
|
||||
## BOOST_OPENMETHOD_DECLARE_OVERRIDER
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
|
||||
```c++
|
||||
#define BOOST_OPENMETHOD_DECLARE_OVERRIDER(NAME, (PARAMETERS...), RETURN_TYPE)
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
Declares an overrider for a method.
|
||||
|
||||
The method is deduced from a call to a method guide function with the
|
||||
overrider's arguments.
|
||||
|
||||
The macro creates several entities in the current scope.
|
||||
|
||||
* A class template that acts as a container for the overriders of the methods
|
||||
called `NAME`:
|
||||
|
||||
```c++
|
||||
template<typename...> BOOST_OPENMETHOD_OVERRIDERS(NAME);
|
||||
```
|
||||
|
||||
* A specialization of the container template for the overrider:
|
||||
|
||||
```c++
|
||||
struct BOOST_OPENMETHOD_OVERRIDERS(NAME)<RETURN_TYPE(PARAMETERS...)> {
|
||||
static auto fn(PARAMETERS...) -> RETURN_TYPE;
|
||||
static auto has_next() -> bool;
|
||||
template<typename... Args>
|
||||
static auto next(typename... Args) -> RETURN_TYPE;
|
||||
};
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
* `fn` is the overrider function.
|
||||
|
||||
* `has_next()` returns `true` if a less specialized overrider exists.
|
||||
|
||||
* `next(Args... args)` calls the next most specialized overrider via the
|
||||
pointer stored in the method's `next<fn>` member variable.
|
||||
|
||||
`BOOST_OPENMETHOD_DECLARE_OVERRIDER` can be called in a header file, with a
|
||||
semicolon after the call. It can be called in a header file, but not multiple
|
||||
times in the same translation unit.
|
||||
|
||||
NOTE: `NAME` must be an *identifier*. Qualified names are not allowed.
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
[#BOOST_OPENMETHOD_DEFAULT_POLICY]
|
||||
|
||||
## BOOST_OPENMETHOD_DEFAULT_POLICY
|
||||
|
||||
### Description
|
||||
|
||||
The name of the default policy.
|
||||
|
||||
`BOOST_OPENMETHOD_DEFAULT_POLICY` is the default value for the `Policy` template
|
||||
parameter of `method`, `use_classes`, and other constructs defined in
|
||||
`<boost/openmethod/core.hpp>`. If it is not defined,
|
||||
`::boost::openmethod::policy::default_policy` is used.
|
||||
|
||||
`BOOST_OPENMETHOD_DEFAULT_POLICY` can be defined by a program to change the
|
||||
default policy globally. Once `<boost/openmethod/core.hpp>` has been included,
|
||||
redefining the symbol has no effect. To override the default policy, proceed as
|
||||
follows:
|
||||
|
||||
1. Include headers under `boost/openmethod/policies/` as needed.
|
||||
2. Create a policy class, and set `BOOST_OPENMETHOD_DEFAULT_POLICY`.
|
||||
3. Include `<boost/openmethod/core.hpp>`.
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
## BOOST_OPENMETHOD_DEFINE_OVERRIDER
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
|
||||
```c++
|
||||
#define BOOST_OPENMETHOD_DEFINE_OVERRIDER(NAME, (PARAMETERS...), RETURN_TYPE)
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
Defines the body of an overrider declared with
|
||||
`BOOST_OPENMETHOD_DECLARE_OVERRIDER`. It should be called in an implementation
|
||||
file, and followed by a function body.
|
||||
|
||||
NOTE: `NAME` must be an *identifier*. Qualified names are not allowed.
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
## BOOST_OPENMETHOD_GUIDE
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
|
||||
```c++
|
||||
#define BOOST_OPENMETHOD_GUIDE(NAME) /* unspecified */
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
Expands to the name of the guide function used to match overriders to methods.
|
||||
@@ -1,61 +0,0 @@
|
||||
|
||||
[#BOOST_OPENMETHOD_OVERRIDE]
|
||||
|
||||
## BOOST_OPENMETHOD_OVERRIDE
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD_OVERRIDE(NAME, (PARAMETERS...), RETURN_TYPE) {
|
||||
// body
|
||||
}
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
`BOOST_OPENMETHOD_OVERRIDE` adds an overrider to a method.
|
||||
|
||||
The method is deduced from a call to a method guide function with the
|
||||
overrider's arguments.
|
||||
|
||||
The macro creates several entities in the current scope.
|
||||
|
||||
* A class template that acts as a container for the overriders of the methods
|
||||
called `NAME`:
|
||||
|
||||
```c++
|
||||
template<typename...> BOOST_OPENMETHOD_OVERRIDERS(NAME);
|
||||
```
|
||||
|
||||
* A specialization of the container template for the overrider:
|
||||
|
||||
```c++
|
||||
struct BOOST_OPENMETHOD_OVERRIDERS(NAME)<RETURN_TYPE(PARAMETERS...)> {
|
||||
static auto fn(PARAMETERS...) -> RETURN_TYPE;
|
||||
static auto has_next() -> bool;
|
||||
template<typename... Args>
|
||||
static auto next(typename... Args) -> RETURN_TYPE;
|
||||
};
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
* `fn` is the overrider function.
|
||||
|
||||
* `has_next()` returns `true` if a less specialized overrider exists.
|
||||
|
||||
* `next(Args... args)` calls the next most specialized overrider via the
|
||||
pointer stored in the method's `next<fn>` member variable.
|
||||
|
||||
Finally, the macro starts the definition of the overrider function:
|
||||
|
||||
```c++
|
||||
auto BOOST_OPENMETHOD_OVERRIDERS(NAME)<RETURN_TYPE(PARAMETERS...)>::fn(
|
||||
PARAMETERS...) -> RETURN_TYPE
|
||||
```
|
||||
|
||||
The block following the call to the macro is the body of the function.
|
||||
|
||||
NOTE: `NAME` must be an *identifier*. Qualified names are not allowed.
|
||||
@@ -1,16 +0,0 @@
|
||||
|
||||
[#BOOST_OPENMETHOD_REGISTER]
|
||||
|
||||
## BOOST_OPENMETHOD_REGISTER
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/macros.hpp>.
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD_REGISTER(TYPE);
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
Creates a static instance of `TYPE`, using a unique generated name.
|
||||
19
doc/Jamfile
19
doc/Jamfile
@@ -1,19 +0,0 @@
|
||||
# Copyright 2018-2024 Peter Dimov
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
project doc/openmethod ;
|
||||
using asciidoctor ;
|
||||
|
||||
html index.html : openmethod.adoc : <asciidoctor-attribute>stylesheet=zajo-dark.css <asciidoctor-attribute>linkcss ;
|
||||
install html_ : index.html skin.png zajo-dark.css zajo-light.css rouge-github.css : <location>html ;
|
||||
|
||||
# pdf openmethod.pdf : openmethod.adoc : <asciidoctor-doctype>book <asciidoctor-attribute>pdf-themesdir=. <asciidoctor-attribute>pdf-theme=openmethod ;
|
||||
# install pdf_ : openmethod.pdf : <location>html ;
|
||||
|
||||
alias boostdoc ;
|
||||
explicit boostdoc ;
|
||||
alias boostrelease : html_ ;
|
||||
explicit boostrelease ;
|
||||
57
doc/Jamfile.v2
Normal file
57
doc/Jamfile.v2
Normal file
@@ -0,0 +1,57 @@
|
||||
import generate ;
|
||||
import path ;
|
||||
import property-set ;
|
||||
import virtual-target ;
|
||||
|
||||
path-constant HERE : . ;
|
||||
|
||||
make html/index.html : build_antora.sh : @run-script ;
|
||||
generate files-to-install : html/index.html : <generating-rule>@delayed-glob ;
|
||||
install install
|
||||
: files-to-install
|
||||
: <location>html
|
||||
<install-source-root>html/openmethod
|
||||
;
|
||||
explicit html/index.html files-to-install ;
|
||||
|
||||
# this runs the antora script
|
||||
actions run-script
|
||||
{
|
||||
bash $(>)
|
||||
}
|
||||
|
||||
# this globs after its sources are created
|
||||
rule delayed-glob ( project name : property-set : sources * )
|
||||
{
|
||||
for local src in $(sources)
|
||||
{
|
||||
# the next line causes the source to be generated immediately
|
||||
# and not later (which it normally would)
|
||||
UPDATE_NOW [ $(src).actualize ] ;
|
||||
}
|
||||
|
||||
# we need to construct the path to the globbed directory;
|
||||
# this path would be <current-project>/antora
|
||||
local root = [ path.root html [ $(project).location ] ] ;
|
||||
local files ;
|
||||
|
||||
# actual globbing happens here
|
||||
for local file in [ path.glob-tree $(root) : * ]
|
||||
{
|
||||
# we have to skip directories, because our match expression accepts anything
|
||||
if [ CHECK_IF_FILE $(file) ]
|
||||
{
|
||||
# we construct a list of targets to copy
|
||||
files += [ virtual-target.from-file $(file:D=) : $(file:D) : $(project) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
# we prepend empty usage requirements to the result
|
||||
return [ property-set.empty ] $(files) ;
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
alias boostdoc ;
|
||||
explicit boostdoc ;
|
||||
alias boostrelease : install ;
|
||||
explicit boostrelease ;
|
||||
@@ -14,5 +14,5 @@ struct abstract_policy {};
|
||||
### Description
|
||||
|
||||
`abstract_policy` is a required base class for a policy. It makes it possible
|
||||
for meta-functions such as `use_classes` to discriminate between user classes
|
||||
for metafunctions such as `use_classes` to discriminate between user classes
|
||||
and the (optional) policy class.
|
||||
|
||||
32
doc/antora.yml
Normal file
32
doc/antora.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Official repository: https://github.com/boostorg/openmethod
|
||||
#
|
||||
|
||||
name: openmethod
|
||||
version: ~
|
||||
title: Boost.OpenMethod
|
||||
start_page: index.adoc
|
||||
asciidoc:
|
||||
attributes:
|
||||
source-language: asciidoc@
|
||||
table-caption: false
|
||||
nav:
|
||||
- modules/ROOT/nav.adoc
|
||||
ext:
|
||||
cpp-reference:
|
||||
config: doc/mrdocs.yml
|
||||
cpp-tagfiles:
|
||||
files:
|
||||
- file: ./doc/tagfiles/boost-openmethod-doxygen.tag.xml
|
||||
base_url: 'xref:reference:'
|
||||
- file: ./doc/tagfiles/boost-openmethod-macros-doxygen.tag.xml
|
||||
base_url: 'xref:reference:'
|
||||
using-namespaces:
|
||||
- boost::openmethod
|
||||
- boost::openmethod::policies
|
||||
- boost::openmethod::aliases
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/policies/basic_policy.hpp>.
|
||||
|
||||
```c++
|
||||
namespace boost::openmethod {
|
||||
|
||||
@@ -13,19 +11,16 @@ namespace policies {
|
||||
template<class Policy, class... Facets>
|
||||
struct basic_policy : abstract_policy, domain<Policy>, Facets... {
|
||||
template<class Facet>
|
||||
static constexpr bool has_facet = /*unspecified*/;
|
||||
static constexpr bool has = /*unspecified*/;
|
||||
|
||||
template<class NewPolicy>
|
||||
using fork = /*unspecified*/;
|
||||
|
||||
template<class... MoreFacets>
|
||||
using add = /*unspecified*/;
|
||||
template<class... Facets>
|
||||
using with = /*unspecified*/;
|
||||
|
||||
template<class Base, class Facet>
|
||||
using replace = /*unspecified*/;
|
||||
|
||||
template<class Base>
|
||||
using remove = /*unspecified*/;
|
||||
template<class... Facets>
|
||||
using without = /*unspecified*/;
|
||||
};
|
||||
|
||||
struct release : basic_policy<release, ...> {};
|
||||
@@ -35,33 +30,36 @@ struct debug : release::add<...> {};
|
||||
} // policies
|
||||
|
||||
#ifdef NDEBUG
|
||||
using default_policy = policies::release;
|
||||
using default_registry = policies::release;
|
||||
#else
|
||||
using default_policy = policies::debug;
|
||||
using default_registry = policies::debug;
|
||||
#endif
|
||||
|
||||
} // boost::openmethod
|
||||
```
|
||||
|
||||
### Headers
|
||||
|
||||
Defined in <boost/openmethod/policies/basic_policy.hpp>. Also available via
|
||||
`<boost/openmethod/core.hpp>` and `<boost/openmethod.hpp>`.
|
||||
|
||||
### Description
|
||||
|
||||
`basic_policy` implements a policy, which consists of a a collection of methods,
|
||||
classes, dispatch data, and facets, which specify how to obtain a pointer to a
|
||||
classes, dispatch data, and policys, which specify how to obtain a pointer to a
|
||||
v-table from an object, how to report errors, whether to perform runtime sanity
|
||||
checks, etc.
|
||||
|
||||
Some of these functionalities require static variables local to the policy.
|
||||
Forthis reason, `basic_policy` uses the CRTP pattern to provide ensure that two
|
||||
different policies - and the facets they contain - get their own copies of the
|
||||
static state.
|
||||
`basic_policy` has state. It uses the Curiously Recurring Template Pattern to
|
||||
allow distinct policies to have distinct sets of static variables.
|
||||
|
||||
### Members
|
||||
|
||||
#### has_facet
|
||||
#### has
|
||||
|
||||
```c++
|
||||
template<class Facet>
|
||||
static constexpr bool has_facet;
|
||||
static constexpr bool has;
|
||||
```
|
||||
|
||||
Evaluates to `true` if _Policy_ contains _Facet_.
|
||||
@@ -73,46 +71,56 @@ template<class NewPolicy>
|
||||
using fork;
|
||||
```
|
||||
|
||||
Creates a new policy from an existing one. _NewPolicy_, and the facets it
|
||||
contains, do not share static variables with the original _Policy_. The new
|
||||
policy does not retain any knowledge of the classes and methods registered in
|
||||
the original.
|
||||
Creates a new policy from an existing one. _NewPolicy_ does not share static
|
||||
variables with the original _Policy_. The new policy does not retain any
|
||||
knowledge of the classes and methods registered in the original.
|
||||
|
||||
#### add
|
||||
`fork` forks the policys in the policy as well: any policy instantiated from a
|
||||
class template is assumed to take a policy as its first template argument. The
|
||||
template is re-instantiated with the new policy as the first arguments, while
|
||||
the other arguments remain the same.
|
||||
|
||||
#### with
|
||||
|
||||
```c++
|
||||
template<class... MoreFacets>
|
||||
using add;
|
||||
template<class... Facets>
|
||||
using with;
|
||||
```
|
||||
|
||||
Creates a new policy by adding _MoreFacets_ to the original policy's collection
|
||||
of facets. The original policy and the new one share static variables.
|
||||
Requires:: _Facets_ is a list of classes that derive from `policy`.
|
||||
|
||||
#### replace
|
||||
Returns:: A new policy containing _Facets_, and the policys from the original
|
||||
that do not have the same category as _Facets_.
|
||||
|
||||
Examples::
|
||||
* `struct dyn_load : default_registry::fork<dyn_load>::with<indirect_vptr> {};` +
|
||||
Creates a policy just like `default_registry`, with an extra indirection added
|
||||
to the v-table pointers. This policy is suitable for use with dynamic loading.
|
||||
* `struct release_with_diags : release::fork<release_with_diags>::with<basic_error_output<release_with_diags>> {};` +
|
||||
Creates a policy just like `release`, except that it prints a diagnostic
|
||||
message before terminating with `abort()`.
|
||||
* `struct default_throw : default_registry::fork<default_throw>::with<throw_error_handler> {};` +
|
||||
Creates a policy just like `default_registry`, except that it reports errors by
|
||||
throwing exceptions, instead of calling a `std::function` like the default
|
||||
error handler does.
|
||||
|
||||
#### without
|
||||
|
||||
```c++
|
||||
template<class Base, class NewFacet>
|
||||
using replace;
|
||||
template<class... Facets>
|
||||
using without;
|
||||
```
|
||||
|
||||
Creates a new policy by replacing the facet in _Policy_ that derives from _Base_
|
||||
with _NewFacet_. It is not an error if _policy_ does not contain such a facet;
|
||||
in that case, the new policy contains the same facet as the original one.
|
||||
Requires:: _Facets_ is a list of policy categories.
|
||||
|
||||
The original policy and the new one share static variables.
|
||||
Returns:: A new policy containing the policys from the original that do not have
|
||||
the same category as _Facets_.
|
||||
|
||||
#### remove
|
||||
|
||||
```c++
|
||||
template<class Base>
|
||||
using remove;
|
||||
```
|
||||
|
||||
Creates a new policy by removing the facet in _Policy_ that derives from _Base_.
|
||||
It is not an error if _policy_ does not contain such a facet; in that case, the
|
||||
new policy contains the same facet as the original one.
|
||||
|
||||
The original policy and the new one share static variables.
|
||||
Examples::
|
||||
* `struct use_map : default_registry::fork<use_map>::with<vptr_map<use_map>>::without<type_hash> {};` +
|
||||
Creates a policy just like `default_registry`, except that it stores pointers to
|
||||
v-table in a `std::unordered_map`. Also removes the hash function, since it
|
||||
will not be used.
|
||||
|
||||
### Non-members
|
||||
|
||||
@@ -122,8 +130,8 @@ The original policy and the new one share static variables.
|
||||
struct release;
|
||||
```
|
||||
|
||||
A policy that contains facet implementations `std_rtti`, `fast_perfect_hash`,
|
||||
`vptr_vector` and `vectored_error_handler`.
|
||||
A policy that contains policys `std_rtti`, `fast_perfect_hash`, `vptr_vector` and
|
||||
`default_error_handler`.
|
||||
|
||||
#### debug
|
||||
|
||||
@@ -131,12 +139,12 @@ A policy that contains facet implementations `std_rtti`, `fast_perfect_hash`,
|
||||
struct debug;
|
||||
```
|
||||
|
||||
The `release` policy with additional facet implementations `runtime_checks`,
|
||||
The `release` policy with additional policy implementations `runtime_checks`,
|
||||
`basic_error_output` and basic_trace_output.
|
||||
|
||||
NOTE: `debug` extends `release` but it does not a fork it. Both policies use the
|
||||
same `domain`.
|
||||
|
||||
#### default_policy
|
||||
#### default_registry
|
||||
|
||||
An alias for `release` if `NDEBUG` is defined, and for `debug` otherwise.
|
||||
|
||||
40
doc/build_antora.sh
Executable file
40
doc/build_antora.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Official repository: https://github.com/boostorg/openmethod
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo "No playbook supplied, using default playbook"
|
||||
PLAYBOOK="local-playbook.yml"
|
||||
else
|
||||
PLAYBOOK=$1
|
||||
fi
|
||||
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
echo "Building documentation with Antora..."
|
||||
echo "Installing npm dependencies..."
|
||||
npm ci
|
||||
|
||||
echo "Building docs in custom dir..."
|
||||
PATH="$(pwd)/node_modules/.bin:${PATH}"
|
||||
export PATH
|
||||
npx antora --clean --fetch "$PLAYBOOK" --stacktrace --log-level all
|
||||
|
||||
echo "Fixing links to non-mrdocs URIs..."
|
||||
|
||||
for f in $(find html -name '*.html'); do
|
||||
perl -i -pe 's{{{(.*?)}}}{<a href="../../../$1.html">$1</a>}g' "$f"
|
||||
done
|
||||
|
||||
echo "Done"
|
||||
@@ -1,92 +0,0 @@
|
||||
|
||||
## Core API
|
||||
|
||||
OpenMethod provides a macro-free interface: the core API. This is useful in
|
||||
certain situations, for example when combining open-methods and templates.
|
||||
|
||||
Let's rewrite the Animals example using the core API. An open-method is
|
||||
implemented as an instance of the `method` template. Its parameters are a
|
||||
function signature and a return type:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
#include <boost/openmethod/core.hpp>
|
||||
|
||||
using namespace boost::openmethod;
|
||||
|
||||
class poke_openmethod;
|
||||
|
||||
using poke = method<
|
||||
poke_openmethod(std::ostream&, virtual_<Animal&>), void>;
|
||||
----
|
||||
|
||||
|
||||
The `poke_openmethod` class acts as the method's identifier: it separates it
|
||||
from other methods with the same signature. The exact name does not really
|
||||
matter, and the class needs not be defined, only declared. Inventing a class
|
||||
name can get tedious, so OpenMethod provides a macro for that:
|
||||
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/core_api.cpp[tag=method]
|
||||
----
|
||||
|
||||
NOTE: BOOST_OPENMETHOD and associated macros use `BOOST_OPENMETHOD_NAME` in
|
||||
their implementation. This makes it possible to mix the "macro" and "core"
|
||||
styles.
|
||||
|
||||
We call the method via the nested function object `fn`:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
poke::fn(std::cout, animal);
|
||||
----
|
||||
|
||||
Overriders are ordinary functions, added to a method using the nested template
|
||||
`override`:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/core_api.cpp[tag=poke_cat]
|
||||
----
|
||||
|
||||
NOTE: `override` can register multiple overriders.
|
||||
|
||||
In C++26, we will be able to use `_` instead of inventing a one-time-use
|
||||
identifier. In the meantime, OpenMethod provides a small convenience macro:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/core_api.cpp[tag=poke_dog]
|
||||
----
|
||||
|
||||
`next` is available from the method's nested `next` template:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/core_api.cpp[tag=poke_bulldog]
|
||||
----
|
||||
|
||||
NOTE: Since the function uses itself as a template argument in its body, its
|
||||
return type cannot be deduced. It must be specified explicitly, either by using
|
||||
the old function declaration style or a trailing return type.
|
||||
|
||||
|
||||
Why not call `poke_dog` directly? We could; however, keep in mind that, in a
|
||||
real program, a translation unit is not necessarily aware of the overriders
|
||||
added elsewhere - especially in presence of dynamic loading.
|
||||
|
||||
We register the classes with `use_classes`:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/core_api.cpp[tag=use_classes]
|
||||
----
|
||||
|
||||
Finally, we call the method via the static member of the method class `fn`:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/core_api.cpp[tag=main]
|
||||
----
|
||||
@@ -1,170 +0,0 @@
|
||||
|
||||
## Custom RTTI
|
||||
|
||||
Stock policies use the `std_rtti` implementation of `rtti`. Here is its full
|
||||
source:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
struct std_rtti : rtti {
|
||||
template<class Class>
|
||||
static constexpr auto is_polymorphic = std::is_polymorphic_v<Class>;
|
||||
|
||||
template<typename T>
|
||||
static type_id static_type() {
|
||||
return reinterpret_cast<type_id>(&typeid(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static type_id dynamic_type(const T& obj) {
|
||||
return reinterpret_cast<type_id>(&typeid(obj));
|
||||
}
|
||||
|
||||
template<class Stream>
|
||||
static void type_name(type_id type, Stream& stream) {
|
||||
stream << reinterpret_cast<const std::type_info*>(type)->name();
|
||||
}
|
||||
|
||||
static std::type_index type_index(type_id type) {
|
||||
return std::type_index(*reinterpret_cast<const std::type_info*>(type));
|
||||
}
|
||||
|
||||
template<typename D, typename B>
|
||||
static D dynamic_cast_ref(B&& obj) {
|
||||
return dynamic_cast<D>(obj);
|
||||
}
|
||||
};
|
||||
----
|
||||
|
||||
* `is_polymorphic` is used to check if a class is polymorphic. This template is
|
||||
required.
|
||||
|
||||
* `static_type` is used by class registration, by `virtual_ptr`{empty}'s "final"
|
||||
constructs, and to format error and trace messages. `T` is not restricted to
|
||||
the classes that appear as virtual parameters. This function is required.
|
||||
|
||||
* `dynamic_type` is used to locate the v-table for an object. This function is
|
||||
usually required. If only the `virtual_ptr` "final" constructs are used, or
|
||||
if `boost_openmethod_vptr` is provided for all the classes in the policy, it
|
||||
can be omitted.
|
||||
|
||||
* `type_name` writes a representation of `type` to `stream`. It is used to format
|
||||
error and trace messages. `Stream` is a lighweight version of `std::ostream`
|
||||
with reduced functionality. It only supports insertion of `const char*`,
|
||||
`std::string_view`, pointers and `std::size_t`. This function is optional;
|
||||
if it is not provided, "type_id(_type_)" is used.
|
||||
|
||||
* `type_index` returns an object that _uniquely_ identifies a class. Some forms
|
||||
of RTTI (most notably, C++'s `typeid` operator) do not guarantee that the
|
||||
type information object for a class is unique within the same program. This
|
||||
function is optional; if not provided, `type` is assumed to be unique, and
|
||||
used as is.
|
||||
|
||||
* `dynamic_cast_ref` casts `obj` to class `D`. `B&&` is either a lvalue reference
|
||||
(possibly cv-qualified) or a rvalue reference. `D` has the same reference
|
||||
category (and cv-qualifier if applicable) as `B`. This function is required
|
||||
only in presence of virtual inheritance.
|
||||
|
||||
Consider a custom RTTI implementation:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
struct Animal {
|
||||
Animal(unsigned type) : type(type) {
|
||||
}
|
||||
|
||||
virtual ~Animal() = default;
|
||||
|
||||
unsigned type;
|
||||
static constexpr unsigned static_type = 1;
|
||||
};
|
||||
|
||||
struct Cat : Animal {
|
||||
Cat() : Animal(static_type) {
|
||||
}
|
||||
|
||||
static constexpr unsigned static_type = 2;
|
||||
};
|
||||
|
||||
// ditto for Dog
|
||||
----
|
||||
|
||||
This scheme has an interesting property: its type ids are monotonically
|
||||
allocated in a small, dense range. Thus, we don't need to hash them. We can use
|
||||
them as indexes in the table of vptrs.
|
||||
|
||||
This time we are going to replace the default policy globally. First we need to
|
||||
define the custom RTTI facet. We must _not_ include
|
||||
`<boost/openmethod/core.hpp>` or any header that includes it yet.
|
||||
|
||||
Here is the facet implementation:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/custom_rtti.cpp[tag=facet]
|
||||
----
|
||||
|
||||
This facet is quite minimal. It does not support virtual inheritance. It would
|
||||
not produce good error or trace messages, because types would be represented by
|
||||
their integer ids.
|
||||
|
||||
This time we create a policy from scratch. For that we use the `basic_policy`
|
||||
CRTP template:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/custom_rtti.cpp[tag=policy]
|
||||
----
|
||||
|
||||
Next, we include the main header. Because `BOOST_OPENMETHOD_DEFAULT_POLICY` is
|
||||
defined, its value is used for the default policy. Then comes the usual example.
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/custom_rtti.cpp[tag=example]
|
||||
----
|
||||
|
||||
This programs works even if standard RTTI is disabled.
|
||||
|
||||
## Deferred RTTI
|
||||
|
||||
In the previous example, the RTTI system assigns types id statically. It is more
|
||||
common to allocate them using a global counter, manipulated by static
|
||||
constructors. This is a problem, because `static_type` is used by class
|
||||
registration. It may read the custom type ids _before_ they are have been
|
||||
initialized.
|
||||
|
||||
The solution is to add the `deferred_static_rtti` facet to the policy; it defers
|
||||
reading the type information until `initialize` is called.
|
||||
|
||||
This time let's support virtual inheritance as well. First the domain classes:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/deferred_custom_rtti.cpp[tag=classes]
|
||||
// ditto for Dog
|
||||
----
|
||||
|
||||
The rtti facet is the same, with one more function:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
struct custom_rtti : bom::policies::rtti {
|
||||
// as before
|
||||
|
||||
include::{examplesdir}/deferred_custom_rtti.cpp[tag=dynamic_cast_ref]
|
||||
};
|
||||
----
|
||||
|
||||
Finally, the policy contains an additional facet - `deferred_static_rtti`:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
struct custom_policy
|
||||
: bom::policies::basic_policy<
|
||||
custom_policy, custom_rtti,
|
||||
bom::policies::deferred_static_rtti, // <-- additional facet
|
||||
bom::policies::vptr_vector<custom_policy>> {};
|
||||
----
|
||||
|
||||
The example is the same as in the previous section.
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
## vectored_error_handler
|
||||
## default_error_handler
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/policies/vectored_error_handler.hpp>.
|
||||
Defined in <boost/openmethod/policies/default_error_handler.hpp>.
|
||||
|
||||
```c++
|
||||
namespace boost::openmethod::policies {
|
||||
|
||||
template<class Policy>
|
||||
class vectored_error_handler : public error_handler {
|
||||
class default_error_handler : public error_handler {
|
||||
public:
|
||||
using error_variant = std::variant<
|
||||
openmethod_error, not_implemented_error, unknown_class_error,
|
||||
@@ -27,7 +27,7 @@ class vectored_error_handler : public error_handler {
|
||||
|
||||
### Description
|
||||
|
||||
`vectored_error_handler` is an implementation of `error_handler` that calls a
|
||||
`default_error_handler` is an implementation of `error_handler` that calls a
|
||||
`std::function` to handle the error.
|
||||
|
||||
### Members
|
||||
@@ -40,7 +40,7 @@ static auto error(const Error& error) -> void;
|
||||
```
|
||||
|
||||
Calls the function last set via `set_error_handler` or, if it was never called,
|
||||
and if _Policy_ contains an `error_output` facet, use it to print a description
|
||||
and if _Policy_ contains an `output` policy, use it to print a description
|
||||
of `error`.
|
||||
|
||||
#### error
|
||||
@@ -15,11 +15,11 @@ struct deferred_static_rtti : rtti {};
|
||||
|
||||
### Description
|
||||
|
||||
`deferred_static_rtti` is a facet that defers collection of static type ids.
|
||||
`deferred_static_rtti` is a policy that defers collection of static type ids.
|
||||
|
||||
Some custom RTTI systems rely on static constructors to assign type ids.
|
||||
OpenMethod itself relies on static constructors to register classes, methods and
|
||||
overriders, calling the `static_type` function from the `rtti` facet in the
|
||||
overriders, calling the `static_type` function from the `rtti` policy in the
|
||||
process. This can result in collecting the type ids _before_ they have been
|
||||
initialized. Adding this facet to a policy moves the collection of type ids to
|
||||
initialized. Adding this policy to a policy moves the collection of type ids to
|
||||
`initialize`.
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
|
||||
## Dynamic Loading
|
||||
|
||||
OpenMethod supports dynamic loading on operating systems that are capable of
|
||||
handling C++ templates correctly during dynamic link. A dynamic library can add
|
||||
classes, methods and overriders to an existing policy. `initialize` must then be
|
||||
called to rebuild the dispatch tables.
|
||||
|
||||
This leads to a problem: any `virtual_ptr` in existence before `initialize` is
|
||||
called again becomes invalid. This also applies to vptrs that are stored inside
|
||||
objects by `with_vptr`.
|
||||
|
||||
NOTE: This applies only to cases where a dynamic library adds to an _existing_
|
||||
policy. Even if the dynamic library itself uses open-methods, for example as an
|
||||
implementation detail, but it uses its own policy, there is no issue.
|
||||
|
||||
The solution is to use a policy that contains the `indirect_vptr` facet. Instead
|
||||
of storing the vptr directly, it stores a reference to the vptr.
|
||||
|
||||
Here is an example:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/dl.hpp[tag=header]
|
||||
----
|
||||
|
||||
NOTE: The policy must be passed to the method as well as the
|
||||
`virtual_ptr`{empty}s.
|
||||
|
||||
The `indirect_vptr` facet tells `virtual_ptr` to use a _reference_ to the vptr,
|
||||
instead of its value. Even tough the value of the vptr changes when `initialize`
|
||||
is called, the vptrs are stored in the same place (the policy's
|
||||
`static_vptr<Class>` variables).
|
||||
|
||||
We can now register the classes and and provide an overrider:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/dl_main.cpp[tag=main]
|
||||
----
|
||||
|
||||
It is not necessary to pass the policy to `BOOST_OPENMETHOD_CLASSES`, because
|
||||
`indirect_vptr` does not have any state. As for `BOOST_OPENMETHOD_OVERRIDE`, it
|
||||
deduces the policy from the method.
|
||||
|
||||
At this point we only have one overrider. Animals of all species ignore one
|
||||
another:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/dl_main.cpp[tag=before_dlopen]
|
||||
----
|
||||
|
||||
Let's load a dynamic library containing this code:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/dl_shared.cpp[tag=dl_shared]
|
||||
----
|
||||
|
||||
Now back to `main`:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/dl_main.cpp[tag=dlopen]
|
||||
----
|
||||
|
||||
After unloading the library, we must call `initialize` again:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/dl_main.cpp[tag=after_dlclose]
|
||||
----
|
||||
@@ -6,17 +6,14 @@
|
||||
Defined in <boost/openmethod/policies/basic_policy.hpp>.
|
||||
|
||||
```c++
|
||||
namespace boost::openmethod::policies {
|
||||
|
||||
namespace boost::openmethod {
|
||||
|
||||
namespace policies {
|
||||
|
||||
struct error_handler;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Defined in <boost/openmethod/types.hpp>.
|
||||
|
||||
```c++
|
||||
namespace boost::openmethod {
|
||||
|
||||
struct openmethod_error {};
|
||||
|
||||
@@ -40,15 +37,15 @@ struct type_mismatch_error : openmethod_error {
|
||||
type_id type;
|
||||
};
|
||||
|
||||
} // boost::openmethod::policies
|
||||
}
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
`error_handler` is a facet that handles errors.
|
||||
`error_handler` is a policy that handles errors.
|
||||
|
||||
When an error is encountered, either during `initialize` or method dispatch, the
|
||||
program is terminated via a call to `abort`. If this facet is present in the
|
||||
program is terminated via a call to `abort`. If this policy is present in the
|
||||
policy, its `error` function is called with an error object. It can prevent
|
||||
termination by throwing an exception.
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
|
||||
## Error Handling
|
||||
|
||||
When an error is encountered, the program is terminated by a call to `abort`. If
|
||||
the policy contains an `error_handler` facet, it provides an `error` member
|
||||
function (or overloaded functions) to be called with an object identifying the
|
||||
error. The `release` and `debug` policies implement the error facet with
|
||||
`vectored_error_handler`, which wraps the error object in a variant, and calls a
|
||||
handler via a `std::function`. By default, it prints a description of the error
|
||||
to `stderr` in the `debug` policy, and does nothing in the `release` policy. The
|
||||
handler can be set with `set_error_handler`:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/vectored_error_handler.cpp[tag=example]
|
||||
----
|
||||
|
||||
Output:
|
||||
|
||||
[source,console]
|
||||
----
|
||||
spin
|
||||
not implemented
|
||||
spin
|
||||
----
|
||||
|
||||
We can also replace the `error_handler` facet with our own. For example:
|
||||
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/throw_error_handler.cpp[tag=example]
|
||||
----
|
||||
|
||||
[source,console]
|
||||
----
|
||||
spin
|
||||
not implemented
|
||||
spin
|
||||
----
|
||||
|
||||
Stock facet `throw_error_handler` does this for all the exception types:
|
||||
|
||||
```c++
|
||||
namespace boost::openmethod::policies {
|
||||
|
||||
struct throw_error_handler : error_handler {
|
||||
template<class Error>
|
||||
[[noreturn]] static auto error(const Error& error) -> void {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost::openmethod::policies
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
## error_output
|
||||
## output
|
||||
|
||||
### Synopsis
|
||||
|
||||
@@ -8,21 +8,21 @@ Defined in <boost/openmethod/policies/basic_policy.hpp>.
|
||||
```c++
|
||||
namespace boost::openmethod::policies {
|
||||
|
||||
struct error_output : facet {};
|
||||
struct output : policy {};
|
||||
|
||||
} // boost::openmethod::policies
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
`error_output` is a facet that provides a stream for writing error messages.
|
||||
`output` is a policy that provides a stream for writing error messages.
|
||||
|
||||
### Requirements
|
||||
|
||||
#### error_stream
|
||||
|
||||
```c++
|
||||
static RestrictedOutputStream error_stream;
|
||||
static LightweightOutputStream error_stream;
|
||||
```
|
||||
|
||||
A static variable that satisfies the requirements of `RestrictedOutputStream`.
|
||||
A static variable that satisfies the requirements of `LightweightOutputStream`.
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
## facet
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in <boost/openmethod/policies/basic_policy.hpp>.
|
||||
|
||||
```c++
|
||||
namespace boost::openmethod::policies {
|
||||
|
||||
struct facet {
|
||||
static auto finalize() -> void;
|
||||
};
|
||||
|
||||
} // boost::openmethod::policies
|
||||
```
|
||||
|
||||
### Description
|
||||
|
||||
`facet` is the base class of all facets. It provides an empty `finalize` static
|
||||
function which can be overriden (via shadowing) by derived classes.
|
||||
|
||||
### Members
|
||||
|
||||
#### finalize
|
||||
|
||||
```c++
|
||||
static auto finalize() -> void;
|
||||
```
|
||||
|
||||
Does nothing.
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
## Friendship
|
||||
|
||||
We can use overrider containers to grant friendship to a specific overrider, or
|
||||
to all the overriders of a method. The name of the container template is
|
||||
returned by `BOOST_OPENMETHOD_OVERRIDERS`. The template argument for a
|
||||
specialization is the signature of the overrider. For example, the overrider of
|
||||
`poke` for `Cat` is:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
BOOST_OPENMETHOD_OVERRIDERS(poke)<
|
||||
void(std::ostream& os, virtual_ptr<Cat> cat)>::fn;
|
||||
----
|
||||
|
||||
We can thus grant friendship to all the overriders of `poke`:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/friendship.cpp[tag=friend_all]
|
||||
----
|
||||
|
||||
Be aware, though, that the overriders of _any_ method called `poke` - with any
|
||||
signature - are granted friendship.
|
||||
|
||||
We can also befriendto individual overriders:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/friendship.cpp[tag=friend]
|
||||
----
|
||||
3
doc/gentags.sh
Executable file
3
doc/gentags.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
mrdocs && cp reference-output/reference.tag.xml tagfiles/boost-openmethod-doxygen.tag.xml
|
||||
@@ -1,193 +0,0 @@
|
||||
|
||||
## Headers and Namespaces
|
||||
|
||||
Most real-life programs will be organized in multiple files and multiple
|
||||
namespaces. OpenMethod interacts with headers and namespaces very naturally,
|
||||
unless using-directives are avoided. In that case, there are a few things to be
|
||||
aware of.
|
||||
|
||||
Let's break the Animals example into headers and namespaces. First we put
|
||||
`Animal` in its own header and namespace:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/headers_namespaces/animal.hpp[]
|
||||
----
|
||||
|
||||
`BOOST_OPENMETHOD` can be placed in a header file. It adds several constructs to
|
||||
the current namespace:
|
||||
|
||||
* It declares (but does not define) a `struct` named after the method.
|
||||
|
||||
* It declares (but does not define) a _guide_ function. It is also named after
|
||||
the method, and it has the same signature (with the `virtual_` decorators
|
||||
stripped). It is used to match methods and overriders. It is never defined and
|
||||
it is "called" only in a non-evaluated context.
|
||||
|
||||
* It defines an inline function with the same name and signature as the
|
||||
method (with the `virtual_` decorators stripped).
|
||||
|
||||
Next, let's implement the `Cat` class, and a derived class, `Chhetah`, in the
|
||||
`felines` namespace:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/headers_namespaces/cat.hpp[]
|
||||
----
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/headers_namespaces/cat.cpp[]
|
||||
----
|
||||
|
||||
`BOOST_OPENMETHOD_CLASSES` should be placed in an implementation file. It can
|
||||
also go in a header file, but this wastes space, as the same registrar will be
|
||||
created in every translation unit that includes the header. It doesn't matter
|
||||
which namespace the macro is called in. It can take be used with any class name
|
||||
in scope, or with qualified names.
|
||||
|
||||
`BOOST_OPENMETHOD_OVERRIDE` uses the guide function declared by
|
||||
`BOOST_OPENMETHOD` to locate a method that can be called with the same arguments
|
||||
as the overrider itself. It "calls" the guide function in a non-evaluated
|
||||
context, passing it a `std::ostream&` and a `virtual_ptr<Cat>`. The return type
|
||||
of the guide function is the method to add the overrider to. Exactly one guide
|
||||
function must match. The normal rules of overload resolution apply. In this
|
||||
case, the guide function is found via argument dependant lookup (ADL).
|
||||
|
||||
The macro adds several constructs to the current namespace:
|
||||
|
||||
* It declares (but does not define) a `struct` template with one type parameter,
|
||||
named after the method. The template acts like a container for overriders.
|
||||
|
||||
* It specializes the template for the signature of the overrider. Inside the
|
||||
struct, it defines the `next` and `has_next` members, and a static function
|
||||
called `fn`. The block following the macro is the body of the `fn` function.
|
||||
|
||||
It follows that `BOOST_OPENMETHOD_OVERRIDE` should be placed in an
|
||||
implementation file. `BOOST_OPENMETHOD_INLINE_OVERRIDE` works like
|
||||
`BOOST_OPENMETHOD_OVERRIDE`, but it defines the `fn` function as inline, so it
|
||||
can be used in a header file.
|
||||
|
||||
The overrider for Cats can be accessed in the same translation unit, after it
|
||||
has been defined, using the `BOOST_OPENMETHOD_OVERRIDER` macro. It expands to
|
||||
the specialization of the overrider container for the overrider's signature. We
|
||||
call the static `fn` function to call the overrider.
|
||||
|
||||
NOTE: The Cheetah overrider calls the specific overrider for `Cat`, for
|
||||
illustration purpose. It is usually better to call `next` instead.
|
||||
|
||||
Let's implement the `Dog` class, in the `canines` namespace. This time we want
|
||||
the overrider to be accessible in other translation units. We can declare an
|
||||
overrider with `BOOST_OPENMETHOD_DECLARE_OVERRIDER`, without actually defining
|
||||
the static function `fn` just yet.
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/headers_namespaces/dog.hpp[]
|
||||
----
|
||||
|
||||
Unlike function declarations, which can occur multiple times in a TU, an
|
||||
overrider declaration cannot. For example, this is illegal:
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD_DECLARE_OVERRIDER(
|
||||
poke, (std::ostream&, virtual_ptr<Dog>), void);
|
||||
|
||||
BOOST_OPENMETHOD_DECLARE_OVERRIDER(
|
||||
poke, (std::ostream&, virtual_ptr<Dog>), void);
|
||||
```
|
||||
|
||||
Now we use `BOOST_OPENMETHOD_DEFINE_OVERRIDER` to define the overrider:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/headers_namespaces/dog.cpp[]
|
||||
----
|
||||
|
||||
Let's look at the main program now. It derived `Bulldog` from `Dog` and provides
|
||||
an overrider for the new class:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/headers_namespaces/main.cpp[]
|
||||
----
|
||||
|
||||
Again ADL plays a role: it helps the overrider (and `main`) to locate the `poke`
|
||||
method.
|
||||
|
||||
This example is the "happy scenario", where namespaces are used conservatively.
|
||||
|
||||
The `OVERRIDE` macros don't interact well with `using` directives. For example
|
||||
this code:
|
||||
|
||||
```c++
|
||||
using namespace animals;
|
||||
using namespace canines;
|
||||
using namespace felines;
|
||||
|
||||
struct Bulldog : Dog {
|
||||
using Dog::Dog;
|
||||
};
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Dog, Bulldog);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
poke, (std::ostream & os, virtual_ptr<Bulldog> dog), void) {
|
||||
next(os, dog);
|
||||
os << " and bites back";
|
||||
}
|
||||
```
|
||||
|
||||
...will fail to compile, with an error like "reference to
|
||||
'poke_boost_openmethod_overriders' is ambiguous". That is because the overrider
|
||||
containers exist in both the canides and felides namespaces, with the same name.
|
||||
|
||||
Finally, the names passed as first arguments to the BOOST_OPENMETHOD and
|
||||
BOOST_OPENMETHOD_OVERRIDE macros must be identifiers. Qualified names are not
|
||||
allowed. Consider:
|
||||
|
||||
```c++
|
||||
using animals::Animal;
|
||||
|
||||
namespace app_specific_behavior {
|
||||
|
||||
BOOST_OPENMETHOD(
|
||||
meet, (std::ostream&, virtual_ptr<Animal>, virtual_ptr<Animal>), void);
|
||||
|
||||
} // namespace app_specific_behavior
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
meet, (std::ostream& os, virtual_ptr<Animal>, virtual_ptr<Animal>), void) {
|
||||
os << "ignore";
|
||||
}
|
||||
```
|
||||
|
||||
Here, the guide function cannot be found, even via ADL. We get an error like
|
||||
"use of undeclared identifier 'meet_boost_openmethod_guide'". How do we solve
|
||||
this? We might be tempted to use a qualified name:
|
||||
`app_specific_behavior::meet`:
|
||||
|
||||
```c++
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
app_specific_behavior::meet,
|
||||
(std::ostream& os, virtual_ptr<Animal>, virtual_ptr<Animal>), void) {
|
||||
os << "ignore";
|
||||
}
|
||||
```
|
||||
|
||||
But `BOOST_OPENMETHOD_OVERRIDE` also uses the name to derive the overrider
|
||||
container's name, using preprocessor token pasting, resulting in an invalid
|
||||
declaration error.
|
||||
|
||||
We need to do is to make `BOOST_OPENMETHOD_OVERRIDE` "see" the guide function.
|
||||
Its name is returned by macro `BOOST_OPENMETHOD_GUIDE(NAME)`. We can use a
|
||||
using-declaration to bring the guide function into the current scope:
|
||||
|
||||
```c++
|
||||
using app_specific_behavior::BOOST_OPENMETHOD_GUIDE(meet);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
meet, (std::ostream& os, virtual_ptr<Animal>, virtual_ptr<Animal>), void) {
|
||||
os << "ignore";
|
||||
}
|
||||
```
|
||||
@@ -1,103 +0,0 @@
|
||||
|
||||
## Hello World
|
||||
|
||||
Consider the following program, intended to demonstrate the basics of virtual
|
||||
functions:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/virtual_func.cpp[tag=code]
|
||||
----
|
||||
|
||||
We are going to rewrite this using open-methods.
|
||||
|
||||
First we remove the `poke` virtual functions from the domain classes:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/hello_world.cpp[tag=domain_classes]
|
||||
----
|
||||
|
||||
Note that the Animal classes do not depend on iostreams anymore. This is a major
|
||||
advantage of open-methods over virtual functions: they make it possible to
|
||||
better organize dependencies.
|
||||
|
||||
Let's implement `poke`. First we need to include the library's main header. It
|
||||
defines a few macros, and injects a name - `virtual_ptr` - in the global
|
||||
namespace.
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/hello_world.cpp[tag=method]
|
||||
----
|
||||
|
||||
This defines a free function called `poke`, which takes two arguments. The first
|
||||
is the `ostream`. The second argument corresponds to the implicit `this` pointer
|
||||
in a virtual function. It is now an explicit argument. Just like with virtual
|
||||
functions, the exact function to execute is selected on the basis of the
|
||||
argument's _dynamic_ type.
|
||||
|
||||
Unlike virtual functions, there is no such thing as a pure open-method that
|
||||
would make a class abstract. It is not possible to determine if an overrider is
|
||||
available from looking at just the current translation unit.
|
||||
|
||||
Let's add overriders for `Cat` and `Dog`:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/hello_world.cpp[tag=overriders]
|
||||
----
|
||||
|
||||
`Bulldog::poke` calls the `poke` it overrides in its `Dog` base. The equivalent
|
||||
for open-methods is `next`, a function that is available only inside the body of
|
||||
an overrider. It calls the next most specific overrider, i.e. what would have
|
||||
been called if the overrider did not exist.
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/hello_world.cpp[tag=next]
|
||||
----
|
||||
|
||||
All classes involved in open-method calls need to be registered using the
|
||||
`BOOST_OPENMETHOD_CLASSES` macro:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/hello_world.cpp[tag=classes]
|
||||
----
|
||||
|
||||
Classes can be registered incrementally, as long as all the direct bases of a
|
||||
class are listed with it in some call(s) to `BOOST_OPENMETHOD_CLASSES`. For
|
||||
example, `Bulldog` can be added in a second call, as long as `Dog` is listed as
|
||||
well:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
// in animals.cpp
|
||||
BOOST_OPENMETHOD_CLASSES(Animal, Cat, Dog);
|
||||
|
||||
// in bulldog.cpp
|
||||
BOOST_OPENMETHOD_CLASSES(Dog, Bulldog);
|
||||
----
|
||||
|
||||
`boost::openmethod::initialize();` must be called before any open-method call.
|
||||
It builds the dispatch tables. Typically this is done in `main`:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/hello_world.cpp[tag=main,indent=0]
|
||||
----
|
||||
|
||||
We call `poke` like any ordinary function. We can pass it the animals by
|
||||
reference, because `virtual_ptr` has a conversion constructor for that:
|
||||
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
include::{examplesdir}/hello_world.cpp[tag=call]
|
||||
----
|
||||
|
||||
NOTE: `virtual_ptr` is more like a reference than a pointer: it cannot be null,
|
||||
and it cannot be re-assigned. The only reason why it is not called `virtual_ref`
|
||||
is to save the name in case it becomes possible to overload the dot operator in
|
||||
future versions of C++.
|
||||
@@ -1,199 +0,0 @@
|
||||
.highlight table td { padding: 5px; }
|
||||
.highlight table pre { margin: 0; }
|
||||
.highlight .cm {
|
||||
color: #999988;
|
||||
font-style: italic;
|
||||
}
|
||||
.highlight .cp {
|
||||
color: #999999;
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .c1 {
|
||||
color: #999988;
|
||||
font-style: italic;
|
||||
}
|
||||
.highlight .cs {
|
||||
color: #999999;
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
.highlight .c, .highlight .cd {
|
||||
color: #999988;
|
||||
font-style: italic;
|
||||
}
|
||||
.highlight .err {
|
||||
}
|
||||
.highlight .gd {
|
||||
color: #000000;
|
||||
background-color: #ffdddd;
|
||||
}
|
||||
.highlight .ge {
|
||||
color: #000000;
|
||||
font-style: italic;
|
||||
}
|
||||
.highlight .gr {
|
||||
color: #aa0000;
|
||||
}
|
||||
.highlight .gh {
|
||||
color: #999999;
|
||||
}
|
||||
.highlight .gi {
|
||||
color: #000000;
|
||||
background-color: #ddffdd;
|
||||
}
|
||||
.highlight .go {
|
||||
color: #888888;
|
||||
}
|
||||
.highlight .gp {
|
||||
color: #555555;
|
||||
}
|
||||
.highlight .gs {
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .gu {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
.highlight .gt {
|
||||
color: #aa0000;
|
||||
}
|
||||
.highlight .kc {
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .kd {
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .kn {
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .kp {
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .kr {
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .kt {
|
||||
color: #445588;
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .k, .highlight .kv {
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .mf {
|
||||
color: #009999;
|
||||
}
|
||||
.highlight .mh {
|
||||
color: #009999;
|
||||
}
|
||||
.highlight .il {
|
||||
color: #009999;
|
||||
}
|
||||
.highlight .mi {
|
||||
color: #009999;
|
||||
}
|
||||
.highlight .mo {
|
||||
color: #009999;
|
||||
}
|
||||
.highlight .m, .highlight .mb, .highlight .mx {
|
||||
color: #009999;
|
||||
}
|
||||
.highlight .sb {
|
||||
color: #d14;
|
||||
}
|
||||
.highlight .sc {
|
||||
color: #d14;
|
||||
}
|
||||
.highlight .sd {
|
||||
color: #d14;
|
||||
}
|
||||
.highlight .s2 {
|
||||
color: #d14;
|
||||
}
|
||||
.highlight .se {
|
||||
color: #d14;
|
||||
}
|
||||
.highlight .sh {
|
||||
color: #d14;
|
||||
}
|
||||
.highlight .si {
|
||||
color: #d14;
|
||||
}
|
||||
.highlight .sx {
|
||||
color: #d14;
|
||||
}
|
||||
.highlight .sr {
|
||||
color: #009926;
|
||||
}
|
||||
.highlight .s1 {
|
||||
color: #d14;
|
||||
}
|
||||
.highlight .ss {
|
||||
color: #990073;
|
||||
}
|
||||
.highlight .s {
|
||||
color: #d14;
|
||||
}
|
||||
.highlight .na {
|
||||
color: #008080;
|
||||
}
|
||||
.highlight .bp {
|
||||
color: #999999;
|
||||
}
|
||||
.highlight .nb {
|
||||
color: #0086B3;
|
||||
}
|
||||
.highlight .nc {
|
||||
color: #445588;
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .no {
|
||||
color: #008080;
|
||||
}
|
||||
.highlight .nd {
|
||||
color: #3c5d5d;
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .ni {
|
||||
color: #800080;
|
||||
}
|
||||
.highlight .ne {
|
||||
color: #990000;
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .nf {
|
||||
color: #990000;
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .nl {
|
||||
color: #990000;
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .nn {
|
||||
color: #555555;
|
||||
}
|
||||
.highlight .nt {
|
||||
color: #000080;
|
||||
}
|
||||
.highlight .vc {
|
||||
color: #008080;
|
||||
}
|
||||
.highlight .vg {
|
||||
color: #008080;
|
||||
}
|
||||
.highlight .vi {
|
||||
color: #008080;
|
||||
}
|
||||
.highlight .nv {
|
||||
color: #008080;
|
||||
}
|
||||
.highlight .ow {
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .o {
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .o {
|
||||
font-weight: bold;
|
||||
}
|
||||
.highlight .w {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.1 KiB |
@@ -1,478 +0,0 @@
|
||||
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
|
||||
/* Uncomment @import statement below to use as custom stylesheet */
|
||||
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
|
||||
|
||||
/* Zajo's custom font import. The rest of the customizations are at the bottom of this css file, which is otherwise kept unchanged */
|
||||
@import "https://fonts.googleapis.com/css?family=Anonymous+Pro|Istok+Web|Quicksand|Poiret+One";
|
||||
|
||||
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
|
||||
audio,canvas,video{display:inline-block}
|
||||
audio:not([controls]){display:none;height:0}
|
||||
script{display:none!important}
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
|
||||
a{background:transparent}
|
||||
a:focus{outline:thin dotted}
|
||||
a:active,a:hover{outline:0}
|
||||
h1{font-size:2em;margin:.67em 0}
|
||||
abbr[title]{border-bottom:1px dotted}
|
||||
b,strong{font-weight:bold}
|
||||
dfn{font-style:italic}
|
||||
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
|
||||
mark{background:#ff0;color:#000}
|
||||
code,kbd,pre,samp{font-family:monospace;font-size:1em}
|
||||
pre{white-space:pre-wrap}
|
||||
q{quotes:"\201C" "\201D" "\2018" "\2019"}
|
||||
small{font-size:80%}
|
||||
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
|
||||
sup{top:-.5em}
|
||||
sub{bottom:-.25em}
|
||||
img{border:0}
|
||||
svg:not(:root){overflow:hidden}
|
||||
figure{margin:0}
|
||||
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
|
||||
legend{border:0;padding:0}
|
||||
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
|
||||
button,input{line-height:normal}
|
||||
button,select{text-transform:none}
|
||||
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
|
||||
button[disabled],html input[disabled]{cursor:default}
|
||||
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
|
||||
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
|
||||
textarea{overflow:auto;vertical-align:top}
|
||||
table{border-collapse:collapse;border-spacing:0}
|
||||
*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
html,body{font-size:100%}
|
||||
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
|
||||
a:hover{cursor:pointer}
|
||||
img,object,embed{max-width:100%;height:auto}
|
||||
object,embed{height:100%}
|
||||
img{-ms-interpolation-mode:bicubic}
|
||||
.left{float:left!important}
|
||||
.right{float:right!important}
|
||||
.text-left{text-align:left!important}
|
||||
.text-right{text-align:right!important}
|
||||
.text-center{text-align:center!important}
|
||||
.text-justify{text-align:justify!important}
|
||||
.hide{display:none}
|
||||
img,object,svg{display:inline-block;vertical-align:middle}
|
||||
textarea{height:auto;min-height:50px}
|
||||
select{width:100%}
|
||||
.center{margin-left:auto;margin-right:auto}
|
||||
.stretch{width:100%}
|
||||
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
|
||||
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
|
||||
a{color:#2156a5;text-decoration:underline;line-height:inherit}
|
||||
a:hover,a:focus{color:#1d4b8f}
|
||||
a img{border:none}
|
||||
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
|
||||
p aside{font-size:.875em;line-height:1.35;font-style:italic}
|
||||
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
|
||||
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
|
||||
h1{font-size:2.125em}
|
||||
h2{font-size:1.6875em}
|
||||
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
|
||||
h4,h5{font-size:1.125em}
|
||||
h6{font-size:1em}
|
||||
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
|
||||
em,i{font-style:italic;line-height:inherit}
|
||||
strong,b{font-weight:bold;line-height:inherit}
|
||||
small{font-size:60%;line-height:inherit}
|
||||
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
|
||||
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
|
||||
ul,ol{margin-left:1.5em}
|
||||
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
|
||||
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
|
||||
ul.square{list-style-type:square}
|
||||
ul.circle{list-style-type:circle}
|
||||
ul.disc{list-style-type:disc}
|
||||
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
|
||||
dl dt{margin-bottom:.3125em;font-weight:bold}
|
||||
dl dd{margin-bottom:1.25em}
|
||||
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
|
||||
abbr{text-transform:none}
|
||||
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
|
||||
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
|
||||
blockquote cite::before{content:"\2014 \0020"}
|
||||
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
|
||||
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
|
||||
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
|
||||
h1{font-size:2.75em}
|
||||
h2{font-size:2.3125em}
|
||||
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
|
||||
h4{font-size:1.4375em}}
|
||||
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
|
||||
table thead,table tfoot{background:#f7f8f7}
|
||||
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
|
||||
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
|
||||
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
|
||||
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
|
||||
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
|
||||
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
|
||||
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
|
||||
.clearfix::after,.float-group::after{clear:both}
|
||||
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
|
||||
*:not(pre)>code.nobreak{word-wrap:normal}
|
||||
*:not(pre)>code.nowrap{white-space:nowrap}
|
||||
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
|
||||
em em{font-style:normal}
|
||||
strong strong{font-weight:400}
|
||||
.keyseq{color:rgba(51,51,51,.8)}
|
||||
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
|
||||
.keyseq kbd:first-child{margin-left:0}
|
||||
.keyseq kbd:last-child{margin-right:0}
|
||||
.menuseq,.menuref{color:#000}
|
||||
.menuseq b:not(.caret),.menuref{font-weight:inherit}
|
||||
.menuseq{word-spacing:-.02em}
|
||||
.menuseq b.caret{font-size:1.25em;line-height:.8}
|
||||
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
|
||||
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
|
||||
b.button::before{content:"[";padding:0 3px 0 2px}
|
||||
b.button::after{content:"]";padding:0 2px 0 3px}
|
||||
p a>code:hover{color:rgba(0,0,0,.9)}
|
||||
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
|
||||
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
|
||||
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
|
||||
#content{margin-top:1.25em}
|
||||
#content::before{content:none}
|
||||
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
|
||||
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
|
||||
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
|
||||
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
|
||||
#header .details span:first-child{margin-left:-.125em}
|
||||
#header .details span.email a{color:rgba(0,0,0,.85)}
|
||||
#header .details br{display:none}
|
||||
#header .details br+span::before{content:"\00a0\2013\00a0"}
|
||||
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
|
||||
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
|
||||
#header #revnumber{text-transform:capitalize}
|
||||
#header #revnumber::after{content:"\00a0"}
|
||||
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
|
||||
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
|
||||
#toc>ul{margin-left:.125em}
|
||||
#toc ul.sectlevel0>li>a{font-style:italic}
|
||||
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
|
||||
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
|
||||
#toc li{line-height:1.3334;margin-top:.3334em}
|
||||
#toc a{text-decoration:none}
|
||||
#toc a:active{text-decoration:underline}
|
||||
#toctitle{color:#7a2518;font-size:1.2em}
|
||||
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
|
||||
body.toc2{padding-left:15em;padding-right:0}
|
||||
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
|
||||
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
|
||||
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
|
||||
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
|
||||
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
|
||||
body.toc2.toc-right{padding-left:0;padding-right:15em}
|
||||
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
|
||||
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
|
||||
#toc.toc2{width:20em}
|
||||
#toc.toc2 #toctitle{font-size:1.375em}
|
||||
#toc.toc2>ul{font-size:.95em}
|
||||
#toc.toc2 ul ul{padding-left:1.25em}
|
||||
body.toc2.toc-right{padding-left:0;padding-right:20em}}
|
||||
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
|
||||
#content #toc>:first-child{margin-top:0}
|
||||
#content #toc>:last-child{margin-bottom:0}
|
||||
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
|
||||
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
|
||||
#content{margin-bottom:.625em}
|
||||
.sect1{padding-bottom:.625em}
|
||||
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
|
||||
.sect1{padding-bottom:1.25em}}
|
||||
.sect1:last-child{padding-bottom:0}
|
||||
.sect1+.sect1{border-top:1px solid #e7e7e9}
|
||||
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
|
||||
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
|
||||
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
|
||||
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
|
||||
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
|
||||
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
|
||||
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
|
||||
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
|
||||
.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
|
||||
table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
|
||||
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
|
||||
.admonitionblock>table td.icon{text-align:center;width:80px}
|
||||
.admonitionblock>table td.icon img{max-width:none}
|
||||
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
|
||||
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)}
|
||||
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
|
||||
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
|
||||
.exampleblock>.content>:first-child{margin-top:0}
|
||||
.exampleblock>.content>:last-child{margin-bottom:0}
|
||||
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
|
||||
.sidebarblock>:first-child{margin-top:0}
|
||||
.sidebarblock>:last-child{margin-bottom:0}
|
||||
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
|
||||
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
|
||||
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
|
||||
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
|
||||
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em}
|
||||
@media screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
|
||||
@media screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
|
||||
.literalblock pre.nowrap,.literalblock pre.nowrap pre,.listingblock pre.nowrap,.listingblock pre.nowrap pre{white-space:pre;word-wrap:normal}
|
||||
.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
|
||||
.listingblock pre.highlightjs{padding:0}
|
||||
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
|
||||
.listingblock pre.prettyprint{border-width:0}
|
||||
.listingblock>.content{position:relative}
|
||||
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
|
||||
.listingblock:hover code[data-lang]::before{display:block}
|
||||
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:#999}
|
||||
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
|
||||
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
|
||||
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
|
||||
table.pyhltable td.code{padding-left:.75em;padding-right:0}
|
||||
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #dddddf}
|
||||
pre.pygments .lineno{display:inline-block;margin-right:.25em}
|
||||
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
|
||||
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
|
||||
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
|
||||
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
|
||||
.quoteblock blockquote{margin:0;padding:0;border:0}
|
||||
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
|
||||
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
|
||||
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
|
||||
.verseblock{margin:0 1em 1.25em}
|
||||
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
|
||||
.verseblock pre strong{font-weight:400}
|
||||
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
|
||||
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
|
||||
.quoteblock .attribution br,.verseblock .attribution br{display:none}
|
||||
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
|
||||
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
|
||||
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
|
||||
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
|
||||
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
|
||||
.quoteblock.excerpt,.quoteblock .quoteblock{margin:0 0 1.25em;padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
|
||||
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
|
||||
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
|
||||
table.tableblock{max-width:100%;border-collapse:separate}
|
||||
p.tableblock:last-child{margin-bottom:0}
|
||||
td.tableblock>.content{margin-bottom:-1.25em}
|
||||
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
|
||||
table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}
|
||||
table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}
|
||||
table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}
|
||||
table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px}
|
||||
table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0}
|
||||
table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}
|
||||
table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}
|
||||
table.frame-all{border-width:1px}
|
||||
table.frame-sides{border-width:0 1px}
|
||||
table.frame-topbot,table.frame-ends{border-width:1px 0}
|
||||
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd){background:#f8f8f7}
|
||||
table.stripes-none tr,table.stripes-odd tr:nth-of-type(even){background:none}
|
||||
th.halign-left,td.halign-left{text-align:left}
|
||||
th.halign-right,td.halign-right{text-align:right}
|
||||
th.halign-center,td.halign-center{text-align:center}
|
||||
th.valign-top,td.valign-top{vertical-align:top}
|
||||
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
|
||||
th.valign-middle,td.valign-middle{vertical-align:middle}
|
||||
table thead th,table tfoot th{font-weight:bold}
|
||||
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
|
||||
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
|
||||
p.tableblock>code:only-child{background:none;padding:0}
|
||||
p.tableblock{font-size:1em}
|
||||
td>div.verse{white-space:pre}
|
||||
ol{margin-left:1.75em}
|
||||
ul li ol{margin-left:1.5em}
|
||||
dl dd{margin-left:1.125em}
|
||||
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
|
||||
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
|
||||
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
|
||||
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
|
||||
ul.unstyled,ol.unstyled{margin-left:0}
|
||||
ul.checklist{margin-left:.625em}
|
||||
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
|
||||
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
|
||||
ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
|
||||
ul.inline>li{margin-left:1.25em}
|
||||
.unstyled dl dt{font-weight:400;font-style:normal}
|
||||
ol.arabic{list-style-type:decimal}
|
||||
ol.decimal{list-style-type:decimal-leading-zero}
|
||||
ol.loweralpha{list-style-type:lower-alpha}
|
||||
ol.upperalpha{list-style-type:upper-alpha}
|
||||
ol.lowerroman{list-style-type:lower-roman}
|
||||
ol.upperroman{list-style-type:upper-roman}
|
||||
ol.lowergreek{list-style-type:lower-greek}
|
||||
.hdlist>table,.colist>table{border:0;background:none}
|
||||
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
|
||||
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
|
||||
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
|
||||
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
|
||||
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
|
||||
.colist td:not([class]):first-child img{max-width:none}
|
||||
.colist td:not([class]):last-child{padding:.25em 0}
|
||||
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
|
||||
.imageblock.left{margin:.25em .625em 1.25em 0}
|
||||
.imageblock.right{margin:.25em 0 1.25em .625em}
|
||||
.imageblock>.title{margin-bottom:0}
|
||||
.imageblock.thumb,.imageblock.th{border-width:6px}
|
||||
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
|
||||
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
|
||||
.image.left{margin-right:.625em}
|
||||
.image.right{margin-left:.625em}
|
||||
a.image{text-decoration:none;display:inline-block}
|
||||
a.image object{pointer-events:none}
|
||||
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
|
||||
sup.footnote a,sup.footnoteref a{text-decoration:none}
|
||||
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
|
||||
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
|
||||
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
|
||||
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
|
||||
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
|
||||
#footnotes .footnote:last-of-type{margin-bottom:0}
|
||||
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
|
||||
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
|
||||
.gist .file-data>table td.line-data{width:99%}
|
||||
div.unbreakable{page-break-inside:avoid}
|
||||
.big{font-size:larger}
|
||||
.small{font-size:smaller}
|
||||
.underline{text-decoration:underline}
|
||||
.overline{text-decoration:overline}
|
||||
.line-through{text-decoration:line-through}
|
||||
.aqua{color:#00bfbf}
|
||||
.aqua-background{background-color:#00fafa}
|
||||
.black{color:#000}
|
||||
.black-background{background-color:#000}
|
||||
.blue{color:#0000bf}
|
||||
.blue-background{background-color:#0000fa}
|
||||
.fuchsia{color:#bf00bf}
|
||||
.fuchsia-background{background-color:#fa00fa}
|
||||
.gray{color:#606060}
|
||||
.gray-background{background-color:#7d7d7d}
|
||||
.green{color:#006000}
|
||||
.green-background{background-color:#007d00}
|
||||
.lime{color:#00bf00}
|
||||
.lime-background{background-color:#00fa00}
|
||||
.maroon{color:#600000}
|
||||
.maroon-background{background-color:#7d0000}
|
||||
.navy{color:#000060}
|
||||
.navy-background{background-color:#00007d}
|
||||
.olive{color:#606000}
|
||||
.olive-background{background-color:#7d7d00}
|
||||
.purple{color:#600060}
|
||||
.purple-background{background-color:#7d007d}
|
||||
.red{color:#bf0000}
|
||||
.red-background{background-color:#fa0000}
|
||||
.silver{color:#909090}
|
||||
.silver-background{background-color:#bcbcbc}
|
||||
.teal{color:#006060}
|
||||
.teal-background{background-color:#007d7d}
|
||||
.white{color:#bfbfbf}
|
||||
.white-background{background-color:#fafafa}
|
||||
.yellow{color:#bfbf00}
|
||||
.yellow-background{background-color:#fafa00}
|
||||
span.icon>.fa{cursor:default}
|
||||
a span.icon>.fa{cursor:inherit}
|
||||
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
|
||||
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
|
||||
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
|
||||
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
|
||||
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
|
||||
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
|
||||
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
|
||||
.conum[data-value] *{color:#fff!important}
|
||||
.conum[data-value]+b{display:none}
|
||||
.conum[data-value]::after{content:attr(data-value)}
|
||||
pre .conum[data-value]{position:relative;top:-.125em}
|
||||
b.conum *{color:inherit!important}
|
||||
.conum:not([data-value]):empty{display:none}
|
||||
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
|
||||
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
|
||||
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
|
||||
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
|
||||
p{margin-bottom:1.25rem}
|
||||
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
|
||||
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
|
||||
.print-only{display:none!important}
|
||||
@page{margin:1.25cm .75cm}
|
||||
@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
|
||||
html{font-size:80%}
|
||||
a{color:inherit!important;text-decoration:underline!important}
|
||||
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
|
||||
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
|
||||
abbr[title]::after{content:" (" attr(title) ")"}
|
||||
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
|
||||
thead{display:table-header-group}
|
||||
svg{max-width:100%}
|
||||
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
|
||||
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
|
||||
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
|
||||
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
|
||||
body.book #header{text-align:center}
|
||||
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
|
||||
body.book #header .details{border:0!important;display:block;padding:0!important}
|
||||
body.book #header .details span:first-child{margin-left:0!important}
|
||||
body.book #header .details br{display:block}
|
||||
body.book #header .details br+span::before{content:none!important}
|
||||
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
|
||||
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
|
||||
.listingblock code[data-lang]::before{display:block}
|
||||
#footer{padding:0 .9375em}
|
||||
.hide-on-print{display:none!important}
|
||||
.print-only{display:block!important}
|
||||
.hide-for-print{display:none!important}
|
||||
.show-for-print{display:inherit!important}}
|
||||
@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
|
||||
.sect1{padding:0!important}
|
||||
.sect1+.sect1{border:0}
|
||||
#footer{background:none}
|
||||
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
|
||||
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
|
||||
|
||||
/* Zajo's customizations applied on top of the standard asciidoctor css above */
|
||||
h1{font-size:4em}
|
||||
h2{font-size:1.74em}
|
||||
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.5em}
|
||||
h4{font-size:1.2em}
|
||||
h5{font-size:1em}
|
||||
h6{font-size:1em}
|
||||
#toc {text-align:left}
|
||||
#toc ul code{font-size:111%}
|
||||
#toc a:hover code {color:#00cc99}
|
||||
a:focus{outline:0}
|
||||
.colist td{color:rgba(255,255,255,.67)}
|
||||
body{text-align:left; background:#202020;color:rgba(255,255,255,.67);padding:0;margin:0;font-family:"Istok Web","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
|
||||
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#a0a0a0;font-weight:400;margin-top:0;margin-bottom:.25em}
|
||||
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#101010}
|
||||
table{background:#202020;margin-bottom:1.25em;border:solid 1px #dedede}
|
||||
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(255,255,255,.67)}
|
||||
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#202020}
|
||||
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{color:rgba(255,255,255,.67)}
|
||||
th{background-color:#404040}
|
||||
a{color:#FFFFFF;text-decoration:underline;line-height:inherit}
|
||||
a:hover{color:#00cc99}
|
||||
a:focus{color:#FFFFFF}
|
||||
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Quicksand","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#00cc99;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.4em}
|
||||
code{font-family:"Anonymous Pro","DejaVu Sans Mono",monospace;font-weight:400;color:black}
|
||||
*:not(pre)>code{font-size:1.0em;font-style:normal!important;letter-spacing:0;padding:0 0;word-spacing:-.15em;background-color:transparent;-webkit-border-radius:0;border-radius:0;line-height:1.45;text-rendering:optimizeLegibility;word-wrap:break-word;color:white}
|
||||
pre,pre>code{line-height:1.45;color:rgba(255,255,255,.67);font-family:"Anonymous Pro","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeLegibility;font-size:1.05em;background-color:#101010}
|
||||
a:not(pre)>code:hover {color:#00cc99}
|
||||
kbd{font-family:"Anonymous Pro","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
|
||||
h1 code{color:#00cc99; font-size:113%}
|
||||
h2 code{color:#00cc99; font-size:113%}
|
||||
h3 code{color:#00cc99; font-size:113%}
|
||||
h4 code{color:#00cc99; font-size:113%}
|
||||
h5 code{color:#00cc99; font-size:113%}
|
||||
#header>h1:first-child{font-family:"Poiret One";color:#00cc99;margin-top:2.25rem;margin-bottom:0;letter-spacing:-.07em}
|
||||
#author{color:#a366ff}
|
||||
#toc ul{font-family:"Quicksand","DejaVu Sans",sans-serif;list-style-type:none}
|
||||
#toc a:hover{color:#00cc99}
|
||||
#toc.toc2{background-color:#404040}
|
||||
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#00cc99}
|
||||
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";color:#00cc99;text-shadow:none}
|
||||
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#a366ff}
|
||||
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#a366ff}
|
||||
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#a366ff}
|
||||
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(255,255,255,.67)}
|
||||
.conum[data-value]{display:inline-block;color:black!important;background-color:#d9d9d9;-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
|
||||
.exampleblock>.content{background-color:#404040;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
|
||||
.quoteblock {background-color:#404040}
|
||||
.quoteblock blockquote,.quoteblock p{color:rgba(255,255,255,.67);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify;background-color:#404040}
|
||||
.quoteblock blockquote::before{margin-left:-.8em;color:#00cc99}
|
||||
.quoteblock blockquote{font-family:"Istok Web","DejaVu Serif"; font-size:1.0625rem; padding:0.5em}
|
||||
.quoteblock .attribution{padding-top:.75ex;margin-top:0;margin-right:0;padding-right:.5ex;text-align:right;background-color:#202020}
|
||||
.text-right{margin-top:-1em}
|
||||
@@ -1,468 +0,0 @@
|
||||
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
|
||||
/* Uncomment @import statement below to use as custom stylesheet */
|
||||
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
|
||||
|
||||
/* Zajo's custom font import. The rest of the customizations are at the bottom of this css file, which is otherwise kept unchanged */
|
||||
@import "https://fonts.googleapis.com/css?family=Anonymous+Pro|Istok+Web|Quicksand|Poiret+One";
|
||||
|
||||
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
|
||||
audio,canvas,video{display:inline-block}
|
||||
audio:not([controls]){display:none;height:0}
|
||||
script{display:none!important}
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
|
||||
a{background:transparent}
|
||||
a:focus{outline:thin dotted}
|
||||
a:active,a:hover{outline:0}
|
||||
h1{font-size:2em;margin:.67em 0}
|
||||
abbr[title]{border-bottom:1px dotted}
|
||||
b,strong{font-weight:bold}
|
||||
dfn{font-style:italic}
|
||||
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
|
||||
mark{background:#ff0;color:#000}
|
||||
code,kbd,pre,samp{font-family:monospace;font-size:1em}
|
||||
pre{white-space:pre-wrap}
|
||||
q{quotes:"\201C" "\201D" "\2018" "\2019"}
|
||||
small{font-size:80%}
|
||||
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
|
||||
sup{top:-.5em}
|
||||
sub{bottom:-.25em}
|
||||
img{border:0}
|
||||
svg:not(:root){overflow:hidden}
|
||||
figure{margin:0}
|
||||
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
|
||||
legend{border:0;padding:0}
|
||||
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
|
||||
button,input{line-height:normal}
|
||||
button,select{text-transform:none}
|
||||
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
|
||||
button[disabled],html input[disabled]{cursor:default}
|
||||
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
|
||||
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
|
||||
textarea{overflow:auto;vertical-align:top}
|
||||
table{border-collapse:collapse;border-spacing:0}
|
||||
*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
html,body{font-size:100%}
|
||||
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
|
||||
a:hover{cursor:pointer}
|
||||
img,object,embed{max-width:100%;height:auto}
|
||||
object,embed{height:100%}
|
||||
img{-ms-interpolation-mode:bicubic}
|
||||
.left{float:left!important}
|
||||
.right{float:right!important}
|
||||
.text-left{text-align:left!important}
|
||||
.text-right{text-align:right!important}
|
||||
.text-center{text-align:center!important}
|
||||
.text-justify{text-align:justify!important}
|
||||
.hide{display:none}
|
||||
img,object,svg{display:inline-block;vertical-align:middle}
|
||||
textarea{height:auto;min-height:50px}
|
||||
select{width:100%}
|
||||
.center{margin-left:auto;margin-right:auto}
|
||||
.stretch{width:100%}
|
||||
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
|
||||
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
|
||||
a{color:#2156a5;text-decoration:underline;line-height:inherit}
|
||||
a:hover,a:focus{color:#1d4b8f}
|
||||
a img{border:none}
|
||||
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
|
||||
p aside{font-size:.875em;line-height:1.35;font-style:italic}
|
||||
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
|
||||
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
|
||||
h1{font-size:2.125em}
|
||||
h2{font-size:1.6875em}
|
||||
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
|
||||
h4,h5{font-size:1.125em}
|
||||
h6{font-size:1em}
|
||||
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
|
||||
em,i{font-style:italic;line-height:inherit}
|
||||
strong,b{font-weight:bold;line-height:inherit}
|
||||
small{font-size:60%;line-height:inherit}
|
||||
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
|
||||
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
|
||||
ul,ol{margin-left:1.5em}
|
||||
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
|
||||
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
|
||||
ul.square{list-style-type:square}
|
||||
ul.circle{list-style-type:circle}
|
||||
ul.disc{list-style-type:disc}
|
||||
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
|
||||
dl dt{margin-bottom:.3125em;font-weight:bold}
|
||||
dl dd{margin-bottom:1.25em}
|
||||
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
|
||||
abbr{text-transform:none}
|
||||
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
|
||||
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
|
||||
blockquote cite::before{content:"\2014 \0020"}
|
||||
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
|
||||
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
|
||||
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
|
||||
h1{font-size:2.75em}
|
||||
h2{font-size:2.3125em}
|
||||
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
|
||||
h4{font-size:1.4375em}}
|
||||
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
|
||||
table thead,table tfoot{background:#f7f8f7}
|
||||
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
|
||||
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
|
||||
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
|
||||
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
|
||||
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
|
||||
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
|
||||
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
|
||||
.clearfix::after,.float-group::after{clear:both}
|
||||
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
|
||||
*:not(pre)>code.nobreak{word-wrap:normal}
|
||||
*:not(pre)>code.nowrap{white-space:nowrap}
|
||||
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
|
||||
em em{font-style:normal}
|
||||
strong strong{font-weight:400}
|
||||
.keyseq{color:rgba(51,51,51,.8)}
|
||||
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
|
||||
.keyseq kbd:first-child{margin-left:0}
|
||||
.keyseq kbd:last-child{margin-right:0}
|
||||
.menuseq,.menuref{color:#000}
|
||||
.menuseq b:not(.caret),.menuref{font-weight:inherit}
|
||||
.menuseq{word-spacing:-.02em}
|
||||
.menuseq b.caret{font-size:1.25em;line-height:.8}
|
||||
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
|
||||
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
|
||||
b.button::before{content:"[";padding:0 3px 0 2px}
|
||||
b.button::after{content:"]";padding:0 2px 0 3px}
|
||||
p a>code:hover{color:rgba(0,0,0,.9)}
|
||||
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
|
||||
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
|
||||
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
|
||||
#content{margin-top:1.25em}
|
||||
#content::before{content:none}
|
||||
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
|
||||
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
|
||||
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
|
||||
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
|
||||
#header .details span:first-child{margin-left:-.125em}
|
||||
#header .details span.email a{color:rgba(0,0,0,.85)}
|
||||
#header .details br{display:none}
|
||||
#header .details br+span::before{content:"\00a0\2013\00a0"}
|
||||
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
|
||||
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
|
||||
#header #revnumber{text-transform:capitalize}
|
||||
#header #revnumber::after{content:"\00a0"}
|
||||
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
|
||||
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
|
||||
#toc>ul{margin-left:.125em}
|
||||
#toc ul.sectlevel0>li>a{font-style:italic}
|
||||
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
|
||||
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
|
||||
#toc li{line-height:1.3334;margin-top:.3334em}
|
||||
#toc a{text-decoration:none}
|
||||
#toc a:active{text-decoration:underline}
|
||||
#toctitle{color:#7a2518;font-size:1.2em}
|
||||
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
|
||||
body.toc2{padding-left:15em;padding-right:0}
|
||||
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
|
||||
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
|
||||
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
|
||||
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
|
||||
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
|
||||
body.toc2.toc-right{padding-left:0;padding-right:15em}
|
||||
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
|
||||
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
|
||||
#toc.toc2{width:20em}
|
||||
#toc.toc2 #toctitle{font-size:1.375em}
|
||||
#toc.toc2>ul{font-size:.95em}
|
||||
#toc.toc2 ul ul{padding-left:1.25em}
|
||||
body.toc2.toc-right{padding-left:0;padding-right:20em}}
|
||||
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
|
||||
#content #toc>:first-child{margin-top:0}
|
||||
#content #toc>:last-child{margin-bottom:0}
|
||||
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
|
||||
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
|
||||
#content{margin-bottom:.625em}
|
||||
.sect1{padding-bottom:.625em}
|
||||
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
|
||||
.sect1{padding-bottom:1.25em}}
|
||||
.sect1:last-child{padding-bottom:0}
|
||||
.sect1+.sect1{border-top:1px solid #e7e7e9}
|
||||
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
|
||||
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
|
||||
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
|
||||
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
|
||||
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
|
||||
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
|
||||
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
|
||||
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
|
||||
.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
|
||||
table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
|
||||
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
|
||||
.admonitionblock>table td.icon{text-align:center;width:80px}
|
||||
.admonitionblock>table td.icon img{max-width:none}
|
||||
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
|
||||
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)}
|
||||
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
|
||||
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
|
||||
.exampleblock>.content>:first-child{margin-top:0}
|
||||
.exampleblock>.content>:last-child{margin-bottom:0}
|
||||
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
|
||||
.sidebarblock>:first-child{margin-top:0}
|
||||
.sidebarblock>:last-child{margin-bottom:0}
|
||||
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
|
||||
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
|
||||
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
|
||||
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
|
||||
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em}
|
||||
@media screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
|
||||
@media screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
|
||||
.literalblock pre.nowrap,.literalblock pre.nowrap pre,.listingblock pre.nowrap,.listingblock pre.nowrap pre{white-space:pre;word-wrap:normal}
|
||||
.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
|
||||
.listingblock pre.highlightjs{padding:0}
|
||||
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
|
||||
.listingblock pre.prettyprint{border-width:0}
|
||||
.listingblock>.content{position:relative}
|
||||
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
|
||||
.listingblock:hover code[data-lang]::before{display:block}
|
||||
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:#999}
|
||||
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
|
||||
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
|
||||
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
|
||||
table.pyhltable td.code{padding-left:.75em;padding-right:0}
|
||||
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #dddddf}
|
||||
pre.pygments .lineno{display:inline-block;margin-right:.25em}
|
||||
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
|
||||
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
|
||||
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
|
||||
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
|
||||
.quoteblock blockquote{margin:0;padding:0;border:0}
|
||||
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
|
||||
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
|
||||
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
|
||||
.verseblock{margin:0 1em 1.25em}
|
||||
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
|
||||
.verseblock pre strong{font-weight:400}
|
||||
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
|
||||
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
|
||||
.quoteblock .attribution br,.verseblock .attribution br{display:none}
|
||||
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
|
||||
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
|
||||
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
|
||||
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
|
||||
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
|
||||
.quoteblock.excerpt,.quoteblock .quoteblock{margin:0 0 1.25em;padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
|
||||
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
|
||||
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
|
||||
table.tableblock{max-width:100%;border-collapse:separate}
|
||||
p.tableblock:last-child{margin-bottom:0}
|
||||
td.tableblock>.content{margin-bottom:-1.25em}
|
||||
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
|
||||
table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}
|
||||
table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}
|
||||
table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}
|
||||
table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px}
|
||||
table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0}
|
||||
table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}
|
||||
table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}
|
||||
table.frame-all{border-width:1px}
|
||||
table.frame-sides{border-width:0 1px}
|
||||
table.frame-topbot,table.frame-ends{border-width:1px 0}
|
||||
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd){background:#f8f8f7}
|
||||
table.stripes-none tr,table.stripes-odd tr:nth-of-type(even){background:none}
|
||||
th.halign-left,td.halign-left{text-align:left}
|
||||
th.halign-right,td.halign-right{text-align:right}
|
||||
th.halign-center,td.halign-center{text-align:center}
|
||||
th.valign-top,td.valign-top{vertical-align:top}
|
||||
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
|
||||
th.valign-middle,td.valign-middle{vertical-align:middle}
|
||||
table thead th,table tfoot th{font-weight:bold}
|
||||
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
|
||||
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
|
||||
p.tableblock>code:only-child{background:none;padding:0}
|
||||
p.tableblock{font-size:1em}
|
||||
td>div.verse{white-space:pre}
|
||||
ol{margin-left:1.75em}
|
||||
ul li ol{margin-left:1.5em}
|
||||
dl dd{margin-left:1.125em}
|
||||
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
|
||||
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
|
||||
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
|
||||
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
|
||||
ul.unstyled,ol.unstyled{margin-left:0}
|
||||
ul.checklist{margin-left:.625em}
|
||||
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
|
||||
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
|
||||
ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
|
||||
ul.inline>li{margin-left:1.25em}
|
||||
.unstyled dl dt{font-weight:400;font-style:normal}
|
||||
ol.arabic{list-style-type:decimal}
|
||||
ol.decimal{list-style-type:decimal-leading-zero}
|
||||
ol.loweralpha{list-style-type:lower-alpha}
|
||||
ol.upperalpha{list-style-type:upper-alpha}
|
||||
ol.lowerroman{list-style-type:lower-roman}
|
||||
ol.upperroman{list-style-type:upper-roman}
|
||||
ol.lowergreek{list-style-type:lower-greek}
|
||||
.hdlist>table,.colist>table{border:0;background:none}
|
||||
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
|
||||
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
|
||||
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
|
||||
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
|
||||
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
|
||||
.colist td:not([class]):first-child img{max-width:none}
|
||||
.colist td:not([class]):last-child{padding:.25em 0}
|
||||
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
|
||||
.imageblock.left{margin:.25em .625em 1.25em 0}
|
||||
.imageblock.right{margin:.25em 0 1.25em .625em}
|
||||
.imageblock>.title{margin-bottom:0}
|
||||
.imageblock.thumb,.imageblock.th{border-width:6px}
|
||||
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
|
||||
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
|
||||
.image.left{margin-right:.625em}
|
||||
.image.right{margin-left:.625em}
|
||||
a.image{text-decoration:none;display:inline-block}
|
||||
a.image object{pointer-events:none}
|
||||
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
|
||||
sup.footnote a,sup.footnoteref a{text-decoration:none}
|
||||
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
|
||||
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
|
||||
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
|
||||
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
|
||||
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
|
||||
#footnotes .footnote:last-of-type{margin-bottom:0}
|
||||
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
|
||||
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
|
||||
.gist .file-data>table td.line-data{width:99%}
|
||||
div.unbreakable{page-break-inside:avoid}
|
||||
.big{font-size:larger}
|
||||
.small{font-size:smaller}
|
||||
.underline{text-decoration:underline}
|
||||
.overline{text-decoration:overline}
|
||||
.line-through{text-decoration:line-through}
|
||||
.aqua{color:#00bfbf}
|
||||
.aqua-background{background-color:#00fafa}
|
||||
.black{color:#000}
|
||||
.black-background{background-color:#000}
|
||||
.blue{color:#0000bf}
|
||||
.blue-background{background-color:#0000fa}
|
||||
.fuchsia{color:#bf00bf}
|
||||
.fuchsia-background{background-color:#fa00fa}
|
||||
.gray{color:#606060}
|
||||
.gray-background{background-color:#7d7d7d}
|
||||
.green{color:#006000}
|
||||
.green-background{background-color:#007d00}
|
||||
.lime{color:#00bf00}
|
||||
.lime-background{background-color:#00fa00}
|
||||
.maroon{color:#600000}
|
||||
.maroon-background{background-color:#7d0000}
|
||||
.navy{color:#000060}
|
||||
.navy-background{background-color:#00007d}
|
||||
.olive{color:#606000}
|
||||
.olive-background{background-color:#7d7d00}
|
||||
.purple{color:#600060}
|
||||
.purple-background{background-color:#7d007d}
|
||||
.red{color:#bf0000}
|
||||
.red-background{background-color:#fa0000}
|
||||
.silver{color:#909090}
|
||||
.silver-background{background-color:#bcbcbc}
|
||||
.teal{color:#006060}
|
||||
.teal-background{background-color:#007d7d}
|
||||
.white{color:#bfbfbf}
|
||||
.white-background{background-color:#fafafa}
|
||||
.yellow{color:#bfbf00}
|
||||
.yellow-background{background-color:#fafa00}
|
||||
span.icon>.fa{cursor:default}
|
||||
a span.icon>.fa{cursor:inherit}
|
||||
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
|
||||
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
|
||||
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
|
||||
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
|
||||
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
|
||||
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
|
||||
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
|
||||
.conum[data-value] *{color:#fff!important}
|
||||
.conum[data-value]+b{display:none}
|
||||
.conum[data-value]::after{content:attr(data-value)}
|
||||
pre .conum[data-value]{position:relative;top:-.125em}
|
||||
b.conum *{color:inherit!important}
|
||||
.conum:not([data-value]):empty{display:none}
|
||||
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
|
||||
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
|
||||
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
|
||||
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
|
||||
p{margin-bottom:1.25rem}
|
||||
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
|
||||
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
|
||||
.print-only{display:none!important}
|
||||
@page{margin:1.25cm .75cm}
|
||||
@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
|
||||
html{font-size:80%}
|
||||
a{color:inherit!important;text-decoration:underline!important}
|
||||
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
|
||||
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
|
||||
abbr[title]::after{content:" (" attr(title) ")"}
|
||||
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
|
||||
thead{display:table-header-group}
|
||||
svg{max-width:100%}
|
||||
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
|
||||
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
|
||||
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
|
||||
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
|
||||
body.book #header{text-align:center}
|
||||
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
|
||||
body.book #header .details{border:0!important;display:block;padding:0!important}
|
||||
body.book #header .details span:first-child{margin-left:0!important}
|
||||
body.book #header .details br{display:block}
|
||||
body.book #header .details br+span::before{content:none!important}
|
||||
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
|
||||
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
|
||||
.listingblock code[data-lang]::before{display:block}
|
||||
#footer{padding:0 .9375em}
|
||||
.hide-on-print{display:none!important}
|
||||
.print-only{display:block!important}
|
||||
.hide-for-print{display:none!important}
|
||||
.show-for-print{display:inherit!important}}
|
||||
@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
|
||||
.sect1{padding:0!important}
|
||||
.sect1+.sect1{border:0}
|
||||
#footer{background:none}
|
||||
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
|
||||
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
|
||||
|
||||
/* Zajo's customizations applied on top of the standard asciidoctor css above */
|
||||
h1{font-size:4em}
|
||||
h2{font-size:1.74em}
|
||||
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.5em}
|
||||
h4{font-size:1.2em}
|
||||
h5{font-size:1em}
|
||||
h6{font-size:1em}
|
||||
#toc {text-align:left}
|
||||
#toc ul code{font-size:111%}
|
||||
#toc a:hover code {color:#4101a7}
|
||||
a:focus{outline:0}
|
||||
.colist td{color:rgba(0,0,0,.67)}
|
||||
body{text-align:left; background:#fff;color:rgba(0,0,0,.67);padding:0;margin:0;font-family:"Istok Web","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
|
||||
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#a0a0a0;font-weight:400;margin-top:0;margin-bottom:.25em}
|
||||
a{color:#000000;text-decoration:underline;line-height:inherit}
|
||||
a:hover{color:#4101a7}
|
||||
a:focus{color:#000000}
|
||||
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Quicksand","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#4101a7;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.4em}
|
||||
code{font-family:"Anonymous Pro","DejaVu Sans Mono",monospace;font-weight:400;color:black}
|
||||
*:not(pre)>code{font-size:1.0em;font-style:normal!important;letter-spacing:0;padding:0 0;word-spacing:-.15em;background-color:transparent;-webkit-border-radius:0;border-radius:0;line-height:1.45;text-rendering:optimizeLegibility;word-wrap:break-word}
|
||||
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Anonymous Pro","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeLegibility;font-size:1.05em;background-color:#f7f8f7}
|
||||
a:not(pre)>code:hover {color:#4101a7}
|
||||
kbd{font-family:"Anonymous Pro","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
|
||||
h1 code{color:#4101a7; font-size:113%}
|
||||
h2 code{color:#4101a7; font-size:113%}
|
||||
h3 code{color:#4101a7; font-size:113%}
|
||||
h4 code{color:#4101a7; font-size:113%}
|
||||
h5 code{color:#4101a7; font-size:113%}
|
||||
#header>h1:first-child{font-family:"Poiret One";color:#ff5100;margin-top:2.25rem;margin-bottom:0;letter-spacing:-.07em}
|
||||
#author{color: #4101a7;}
|
||||
#toc ul{font-family:"Quicksand","DejaVu Sans",sans-serif;list-style-type:none}
|
||||
#toc a:hover{color:#4101a7}
|
||||
#toc.toc2{background-color:#f7f8f7}
|
||||
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#606060}
|
||||
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";color:#606060;text-shadow:none}
|
||||
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#ff5100}
|
||||
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#ff5100}
|
||||
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#ff5100}
|
||||
.conum[data-value]{display:inline-block;color:#fff!important;background-color:#606060;-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
|
||||
.exampleblock>.content{background-color:#ffffff;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
|
||||
.quoteblock blockquote::before{margin-left:-.8em;color:#4101a7}
|
||||
.quoteblock blockquote{font-family:"Istok Web","DejaVu Serif"; font-size:1.0625rem; padding:0.5em}
|
||||
.text-right{margin-top:-1em}
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in `<boost/openmethod/compiler.hpp>`.
|
||||
Defined in `<boost/openmethod/initialize.hpp>`.
|
||||
|
||||
```c++
|
||||
namespace boost::openmethod {
|
||||
|
||||
template<class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY>
|
||||
auto compiler<Policy>::initialize() -> /*unspecified*/;
|
||||
template<class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY>
|
||||
auto initialize() -> /*unspecified*/;
|
||||
|
||||
}
|
||||
```
|
||||
@@ -37,12 +37,12 @@ combination of virtual arguments.
|
||||
|
||||
### Synopsis
|
||||
|
||||
Defined in `<boost/openmethod/compiler.hpp>`.
|
||||
Defined in `<boost/openmethod/initialize.hpp>`.
|
||||
|
||||
```c++
|
||||
namespace boost::openmethod {
|
||||
|
||||
template<class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY>
|
||||
template<class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY>
|
||||
auto finalize() -> void;
|
||||
|
||||
}
|
||||
@@ -51,7 +51,7 @@ auto finalize() -> void;
|
||||
### Description
|
||||
|
||||
De-allocates the resources allocated by `initialize` for the `Policy`, including
|
||||
resources allocated by the facets in `Policy`. Resources are de-allocated in an
|
||||
resources allocated by the policys in `Policy`. Resources are de-allocated in an
|
||||
arbitrary order. It is not necessary to call `finalize` between calls to
|
||||
`initialize`. It is provided mainly for the benefit of memory leak detection
|
||||
schemes.
|
||||
|
||||
@@ -9,11 +9,11 @@ the Expression Problem:
|
||||
to add new operations on the existing types, and new types to the existing
|
||||
operations, without modifying existing code?
|
||||
|
||||
Open-methods also address the banana-gorilla-jungle problem:
|
||||
Open-methods also address the banana-gorilla-shared problem:
|
||||
|
||||
> The problem with object-oriented languages is they’ve got all this implicit
|
||||
environment that they carry around with them. You wanted a banana but what you
|
||||
got was a gorilla holding the banana and the entire jungle. — Joe Armstrong,
|
||||
got was a gorilla holding the banana and the entire shared. — Joe Armstrong,
|
||||
creator of Erlang progamming language
|
||||
|
||||
As a bonus, open-methods can take more than one argument into account when
|
||||
|
||||
57
doc/local-playbook.yml
Normal file
57
doc/local-playbook.yml
Normal file
@@ -0,0 +1,57 @@
|
||||
#
|
||||
# Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
# Official repository: https://github.com/boostorg/openmethod
|
||||
#
|
||||
|
||||
# An antora playbook used for local development
|
||||
# The playbook includes Boost.OpenMethod as its only component
|
||||
|
||||
site:
|
||||
title: Boost.OpenMethod
|
||||
url: https://antora.cppalliance.org/develop/lib/doc
|
||||
start_page: openmethod::index.adoc
|
||||
robots: allow
|
||||
keys:
|
||||
repo_url: 'https://github.com/boostorg/openmethod'
|
||||
|
||||
content:
|
||||
sources:
|
||||
- url: ..
|
||||
start_path: doc
|
||||
edit_url: 'https://github.com/boostorg/openmethod/edit/{refname}/{path}'
|
||||
|
||||
ui:
|
||||
bundle:
|
||||
url: https://github.com/boostorg/website-v2-docs/releases/download/ui-master/ui-bundle.zip
|
||||
snapshot: true
|
||||
|
||||
output:
|
||||
dir: html
|
||||
|
||||
antora:
|
||||
extensions:
|
||||
- require: '@antora/lunr-extension' # https://gitlab.com/antora/antora-lunr-extension
|
||||
index_latest_only: true
|
||||
- require: '@cppalliance/antora-cpp-tagfiles-extension'
|
||||
cpp-tagfiles:
|
||||
using-namespaces:
|
||||
- 'boost::'
|
||||
- require: '@cppalliance/antora-cpp-reference-extension'
|
||||
dependencies:
|
||||
- name: 'boost'
|
||||
repo: 'https://github.com/boostorg/boost.git'
|
||||
tag: 'develop'
|
||||
variable: 'BOOST_SRC_DIR'
|
||||
system-env: 'BOOST_SRC_DIR'
|
||||
|
||||
asciidoc:
|
||||
attributes:
|
||||
# Enable pagination
|
||||
page-pagination: ''
|
||||
extensions:
|
||||
- '@cppalliance/asciidoctor-boost-links'
|
||||
- '@asciidoctor/tabs'
|
||||
@@ -9,7 +9,7 @@ namespace boost::openmethod {
|
||||
|
||||
template<
|
||||
typename Method, typename ReturnType,
|
||||
class Policy = BOOST_OPENMETHOD_DEFAULT_POLICY>
|
||||
class Policy = BOOST_OPENMETHOD_DEFAULT_REGISTRY>
|
||||
class method;
|
||||
|
||||
template<typename Name, typename... Parameters, typename ReturnType, class Policy>
|
||||
|
||||
@@ -15,13 +15,13 @@ struct minimal_rtti : rtti {
|
||||
|
||||
### Description
|
||||
|
||||
`minimal_rtti` is an implementation of the `rtti` facet that only uses static
|
||||
`minimal_rtti` is an implementation of the `rtti` policy that only uses static
|
||||
type information.
|
||||
|
||||
`minimal_rtti` provides the only function strictly required for the `rtti`
|
||||
facet.
|
||||
policy.
|
||||
|
||||
This facet can be used in programs that call methods solely via
|
||||
This policy can be used in programs that call methods solely via
|
||||
`virtual_ptr`{empty}s created with the "final" constructs. Virtual inheritance
|
||||
is not supported. Classes are not required to be polymorphic.
|
||||
|
||||
@@ -35,7 +35,7 @@ template<class Class>
|
||||
static constexpr bool is_polymorphic = false;
|
||||
```
|
||||
|
||||
This facet does not support polymorphic classes.
|
||||
This policy does not support polymorphic classes.
|
||||
|
||||
#### static_type
|
||||
|
||||
|
||||
66
doc/modules/ROOT/examples/CMakeLists.txt
Normal file
66
doc/modules/ROOT/examples/CMakeLists.txt
Normal file
@@ -0,0 +1,66 @@
|
||||
# Copyright (c) 2018-2024 Jean-Louis Leroy
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt
|
||||
# or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
message(STATUS "Boost.OpenMethod: building examples")
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(-save-temps=obj -masm=intel)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_compile_definitions(BOOST_OPENMETHOD_ENABLE_RUNTIME_CHECKS)
|
||||
endif()
|
||||
|
||||
file(GLOB cpp_files "*.cpp")
|
||||
|
||||
foreach (cpp ${cpp_files})
|
||||
get_filename_component(stem ${cpp} NAME_WE)
|
||||
set(test_target "boost_openmethod-${stem}")
|
||||
add_executable(${test_target} ${cpp})
|
||||
target_link_libraries(${test_target} PRIVATE Boost::openmethod Boost::unit_test_framework)
|
||||
add_test(NAME ${test_target} COMMAND ${test_target})
|
||||
add_dependencies(tests ${test_target})
|
||||
endforeach()
|
||||
|
||||
function(boost_openmethod_add_step_by_step dir)
|
||||
set(add_test "")
|
||||
if(ARGC GREATER 1)
|
||||
set(add_test "${ARGV1}")
|
||||
else()
|
||||
set(add_test "ON")
|
||||
endif()
|
||||
|
||||
file(GLOB subdirs "${dir}/*")
|
||||
|
||||
foreach (subdir ${subdirs})
|
||||
string(REGEX REPLACE ".*/" "" subex ${subdir})
|
||||
file(GLOB cpp_files "${subdir}/*.cpp")
|
||||
set(target "boost_openmethod-${dir}_${subex}")
|
||||
add_executable(${target} ${cpp_files})
|
||||
target_link_libraries(${target} PRIVATE Boost::openmethod)
|
||||
set(output_dir openmethod/${dir}/${subex})
|
||||
set_target_properties(${target} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${output_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${output_dir}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${output_dir}"
|
||||
)
|
||||
if(${add_test})
|
||||
add_test(NAME "${target}" COMMAND "${target}")
|
||||
endif()
|
||||
add_dependencies(tests "${target}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
boost_openmethod_add_step_by_step(rolex)
|
||||
boost_openmethod_add_step_by_step(ambiguities OFF)
|
||||
boost_openmethod_add_step_by_step(core_api)
|
||||
boost_openmethod_add_step_by_step(custom_rtti)
|
||||
boost_openmethod_add_step_by_step(virtual_ptr_alt)
|
||||
|
||||
if (NOT WIN32)
|
||||
add_subdirectory(shared_libs)
|
||||
endif()
|
||||
@@ -8,11 +8,10 @@
|
||||
#include <string>
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/shared_ptr.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/interop/std_shared_ptr.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
using boost::openmethod::make_shared_virtual;
|
||||
using boost::openmethod::shared_virtual_ptr;
|
||||
using namespace boost::openmethod::aliases;
|
||||
|
||||
using std::cout;
|
||||
using std::string;
|
||||
@@ -42,8 +41,8 @@ struct Times : Node {
|
||||
shared_virtual_ptr<const Node> left, right;
|
||||
};
|
||||
|
||||
struct Integer : Node {
|
||||
explicit Integer(int value) : value(value) {
|
||||
struct Variable : Node {
|
||||
explicit Variable(int value) : value(value) {
|
||||
}
|
||||
int value;
|
||||
};
|
||||
@@ -51,23 +50,23 @@ struct Integer : Node {
|
||||
// =============================================================================
|
||||
// add behavior to existing classes, without changing them
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Node, Plus, Times, Integer);
|
||||
BOOST_OPENMETHOD_CLASSES(Node, Plus, Times, Variable);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// evaluate
|
||||
|
||||
BOOST_OPENMETHOD(value, (virtual_ptr<const Node>), int);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Plus> expr), int) {
|
||||
return value(expr->left) + value(expr->right);
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Plus> node), int) {
|
||||
return value(node->left) + value(node->right);
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Times> expr), int) {
|
||||
return value(expr->left) * value(expr->right);
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Times> node), int) {
|
||||
return value(node->left) * value(node->right);
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Integer> expr), int) {
|
||||
return expr->value;
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Variable> node), int) {
|
||||
return node->value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -75,16 +74,16 @@ BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Integer> expr), int) {
|
||||
|
||||
BOOST_OPENMETHOD(as_forth, (virtual_ptr<const Node>), string);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_forth, (virtual_ptr<const Plus> expr), string) {
|
||||
return as_forth(expr->left) + " " + as_forth(expr->right) + " +";
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_forth, (virtual_ptr<const Plus> node), string) {
|
||||
return as_forth(node->left) + " " + as_forth(node->right) + " +";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_forth, (virtual_ptr<const Times> expr), string) {
|
||||
return as_forth(expr->left) + " " + as_forth(expr->right) + " *";
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_forth, (virtual_ptr<const Times> node), string) {
|
||||
return as_forth(node->left) + " " + as_forth(node->right) + " *";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_forth, (virtual_ptr<const Integer> expr), string) {
|
||||
return std::to_string(expr->value);
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_forth, (virtual_ptr<const Variable> node), string) {
|
||||
return std::to_string(node->value);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -92,16 +91,16 @@ BOOST_OPENMETHOD_OVERRIDE(as_forth, (virtual_ptr<const Integer> expr), string) {
|
||||
|
||||
BOOST_OPENMETHOD(as_lisp, (virtual_ptr<const Node>), string);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_lisp, (virtual_ptr<const Plus> expr), string) {
|
||||
return "(plus " + as_lisp(expr->left) + " " + as_lisp(expr->right) + ")";
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_lisp, (virtual_ptr<const Plus> node), string) {
|
||||
return "(plus " + as_lisp(node->left) + " " + as_lisp(node->right) + ")";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_lisp, (virtual_ptr<const Times> expr), string) {
|
||||
return "(times " + as_lisp(expr->left) + " " + as_lisp(expr->right) + ")";
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_lisp, (virtual_ptr<const Times> node), string) {
|
||||
return "(times " + as_lisp(node->left) + " " + as_lisp(node->right) + ")";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_lisp, (virtual_ptr<const Integer> expr), string) {
|
||||
return std::to_string(expr->value);
|
||||
BOOST_OPENMETHOD_OVERRIDE(as_lisp, (virtual_ptr<const Variable> node), string) {
|
||||
return std::to_string(node->value);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -109,14 +108,14 @@ BOOST_OPENMETHOD_OVERRIDE(as_lisp, (virtual_ptr<const Integer> expr), string) {
|
||||
auto main() -> int {
|
||||
boost::openmethod::initialize();
|
||||
|
||||
shared_virtual_ptr<Node> expr = make_shared_virtual<Times>(
|
||||
make_shared_virtual<Integer>(2),
|
||||
shared_virtual_ptr<Node> node = make_shared_virtual<Times>(
|
||||
make_shared_virtual<Variable>(2),
|
||||
make_shared_virtual<Plus>(
|
||||
make_shared_virtual<Integer>(3), make_shared_virtual<Integer>(4)));
|
||||
make_shared_virtual<Variable>(3), make_shared_virtual<Variable>(4)));
|
||||
|
||||
cout << as_forth(expr) << " = " << as_lisp(expr) << " = " << value(expr)
|
||||
cout << as_forth(node) << " = " << as_lisp(node) << " = " << value(node)
|
||||
<< "\n";
|
||||
// error_output:
|
||||
// output:
|
||||
// 2 3 4 + * = (times 2 (plus 3 4)) = 14
|
||||
|
||||
return 0;
|
||||
@@ -8,7 +8,9 @@
|
||||
#include <string>
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
struct Character {
|
||||
virtual ~Character() {
|
||||
@@ -42,35 +44,31 @@ BOOST_OPENMETHOD(
|
||||
std::string);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
fight,
|
||||
(virtual_ptr<Character> x, virtual_ptr<Creature> y, virtual_ptr<Banana> z),
|
||||
fight, (virtual_ptr<Character>, virtual_ptr<Creature>, virtual_ptr<Banana>),
|
||||
std::string) {
|
||||
return "are you insane?";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
fight,
|
||||
(virtual_ptr<Character> x, virtual_ptr<Creature> y, virtual_ptr<Axe> z),
|
||||
fight, (virtual_ptr<Character>, virtual_ptr<Creature>, virtual_ptr<Axe>),
|
||||
std::string) {
|
||||
return "not agile enough to wield";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
fight,
|
||||
(virtual_ptr<Warrior> x, virtual_ptr<Creature> y, virtual_ptr<Axe> z),
|
||||
fight, (virtual_ptr<Warrior>, virtual_ptr<Creature>, virtual_ptr<Axe>),
|
||||
std::string) {
|
||||
return "and cuts it into pieces";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
fight, (virtual_ptr<Warrior> x, virtual_ptr<Dragon> y, virtual_ptr<Axe> z),
|
||||
fight, (virtual_ptr<Warrior>, virtual_ptr<Dragon>, virtual_ptr<Axe>),
|
||||
std::string) {
|
||||
return "and dies a honorable death";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
fight,
|
||||
(virtual_ptr<Character> x, virtual_ptr<Dragon> y, virtual_ptr<Hands> z),
|
||||
fight, (virtual_ptr<Character>, virtual_ptr<Dragon>, virtual_ptr<Hands>),
|
||||
std::string) {
|
||||
return "Congratulations! You have just vainquished a dragon with your bare "
|
||||
"hands"
|
||||
38
doc/modules/ROOT/examples/ambiguities/1/main.cpp
Normal file
38
doc/modules/ROOT/examples/ambiguities/1/main.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
// tag::content[]
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct Matrix { virtual ~Matrix() = default; };
|
||||
struct DenseMatrix : Matrix {};
|
||||
struct SparseMatrix : Matrix {};
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Matrix, DenseMatrix, SparseMatrix);
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
BOOST_OPENMETHOD(
|
||||
add, (virtual_ptr<const Matrix>, virtual_ptr<const Matrix>), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
add, (virtual_ptr<const Matrix>, virtual_ptr<const SparseMatrix>), void) {
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
add, (virtual_ptr<const SparseMatrix>, virtual_ptr<const Matrix>), void) {
|
||||
}
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
|
||||
SparseMatrix a, b;
|
||||
add(a, b);
|
||||
}
|
||||
// end::content[]
|
||||
42
doc/modules/ROOT/examples/ambiguities/2/main.cpp
Normal file
42
doc/modules/ROOT/examples/ambiguities/2/main.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct Matrix { virtual ~Matrix() = default; };
|
||||
struct DenseMatrix : Matrix {};
|
||||
struct SparseMatrix : Matrix {};
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Matrix, DenseMatrix, SparseMatrix);
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
BOOST_OPENMETHOD(
|
||||
add, (virtual_ptr<const Matrix>, virtual_ptr<const Matrix>), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
add, (virtual_ptr<const Matrix>, virtual_ptr<const SparseMatrix>), void) {
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
add, (virtual_ptr<const SparseMatrix>, virtual_ptr<const Matrix>), void) {
|
||||
}
|
||||
|
||||
// tag::content[]
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
add, (virtual_ptr<const SparseMatrix>, virtual_ptr<const SparseMatrix>), void) {
|
||||
}
|
||||
// end::content[]
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
|
||||
SparseMatrix a, b;
|
||||
add(a, b);
|
||||
}
|
||||
90
doc/modules/ROOT/examples/ast.cpp
Normal file
90
doc/modules/ROOT/examples/ast.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
// tag::content[]
|
||||
struct Node {
|
||||
virtual ~Node() {}
|
||||
virtual int value() const = 0;
|
||||
};
|
||||
|
||||
struct Variable : Node {
|
||||
Variable(int value) : v(value) {}
|
||||
int value() const override { return v; }
|
||||
int v;
|
||||
};
|
||||
|
||||
struct Plus : Node {
|
||||
Plus(const Node& left, const Node& right) : left(left), right(right) {}
|
||||
int value() const override { return left.value() + right.value(); }
|
||||
const Node& left; const Node& right;
|
||||
};
|
||||
|
||||
struct Times : Node {
|
||||
Times(const Node& left, const Node& right) : left(left), right(right) {}
|
||||
int value() const override { return left.value() * right.value(); }
|
||||
const Node& left; const Node& right;
|
||||
};
|
||||
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// library code
|
||||
// =============================================================================
|
||||
// application code
|
||||
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
BOOST_OPENMETHOD(postfix, (virtual_ptr<const Node> node, std::ostream& os), void);
|
||||
|
||||
// tag::variable_overrider[]
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Variable> var, std::ostream& os), void) {
|
||||
os << var->v;
|
||||
}
|
||||
// end::variable_overrider[]
|
||||
|
||||
// tag::plus_overrider[]
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Plus> plus, std::ostream& os), void) {
|
||||
postfix(plus->left, os);
|
||||
os << ' ';
|
||||
postfix(plus->right, os);
|
||||
os << " +";
|
||||
}
|
||||
// end::plus_overrider[]
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Times> times, std::ostream& os), void) {
|
||||
postfix(times->left, os);
|
||||
os << ' ';
|
||||
postfix(times->right, os);
|
||||
os << " *";
|
||||
}
|
||||
|
||||
// tag::class_registration[]
|
||||
BOOST_OPENMETHOD_CLASSES(Node, Variable, Plus, Times);
|
||||
// end::class_registration[]
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
Variable a{2}, b{3}, c{4};
|
||||
Plus d{a, b}; Times e{d, c};
|
||||
postfix(e, std::cout);
|
||||
std::cout << " = " << e.value() << "\n"; // 2 3 + 4 * = 20
|
||||
}
|
||||
// end::content[]
|
||||
|
||||
void call_via_ref(const Node& node, std::ostream& os) {
|
||||
postfix(node, os);
|
||||
}
|
||||
|
||||
void call_via_virtual_ptr(virtual_ptr<const Node> node, std::ostream& os) {
|
||||
postfix(node, os);
|
||||
}
|
||||
86
doc/modules/ROOT/examples/ast_final_virtual_ptr.cpp
Normal file
86
doc/modules/ROOT/examples/ast_final_virtual_ptr.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
// tag::content[]
|
||||
#include <boost/openmethod.hpp>
|
||||
using namespace boost::openmethod::aliases;
|
||||
|
||||
struct Node {
|
||||
};
|
||||
|
||||
struct Variable : Node {
|
||||
Variable(int value) : v(value) {}
|
||||
int v;
|
||||
};
|
||||
|
||||
struct Plus : Node {
|
||||
Plus(virtual_ptr<const Node> left, virtual_ptr<const Node> right)
|
||||
: left(left), right(right) {}
|
||||
virtual_ptr<const Node> left, right;
|
||||
};
|
||||
|
||||
struct Times : Node {
|
||||
Times(virtual_ptr<const Node> left, virtual_ptr<const Node> right)
|
||||
: left(left), right(right) {}
|
||||
virtual_ptr<const Node> left, right;
|
||||
};
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
BOOST_OPENMETHOD(value, (virtual_ptr<const Node>), int);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Variable> node), int) {
|
||||
return node->v;
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Plus> node), int) {
|
||||
return value(node->left) + value(node->right);
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Times> node), int) {
|
||||
return value(node->left) * value(node->right);
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD(postfix, (virtual_ptr<const Node> node, std::ostream& os), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Variable> var, std::ostream& os), void) {
|
||||
os << var->v;
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Plus> plus, std::ostream& os), void) {
|
||||
postfix(plus->left, os);
|
||||
os << ' ';
|
||||
postfix(plus->right, os);
|
||||
os << " +";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Times> times, std::ostream& os), void) {
|
||||
postfix(times->left, os);
|
||||
os << ' ';
|
||||
postfix(times->right, os);
|
||||
os << " *";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Node, Variable, Plus, Times);
|
||||
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
Variable a{2}, b{3}, c{4};
|
||||
Plus d{final_virtual_ptr(a), final_virtual_ptr(b)};
|
||||
Times e{final_virtual_ptr(d), final_virtual_ptr(c)};
|
||||
auto root = final_virtual_ptr(e);
|
||||
postfix(root, std::cout);
|
||||
std::cout << " = " << value(root) << "\n"; // 2 3 + 4 * = 20
|
||||
}
|
||||
// end::content[]
|
||||
80
doc/modules/ROOT/examples/ast_unique_ptr.cpp
Normal file
80
doc/modules/ROOT/examples/ast_unique_ptr.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
// tag::content[]
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/interop/std_unique_ptr.hpp>
|
||||
|
||||
using namespace boost::openmethod::aliases;
|
||||
|
||||
struct Node {
|
||||
virtual ~Node() {}
|
||||
virtual int value() const = 0;
|
||||
};
|
||||
|
||||
struct Variable : Node {
|
||||
Variable(int value) : v(value) {}
|
||||
int value() const override { return v; }
|
||||
int v;
|
||||
};
|
||||
|
||||
struct Plus : Node {
|
||||
Plus(unique_virtual_ptr<const Node> left, unique_virtual_ptr<const Node> right)
|
||||
: left(std::move(left)), right(std::move(right)) {}
|
||||
int value() const override { return left->value() + right->value(); }
|
||||
unique_virtual_ptr<const Node> left, right;
|
||||
};
|
||||
|
||||
struct Times : Node {
|
||||
Times(unique_virtual_ptr<const Node> left, unique_virtual_ptr<const Node> right)
|
||||
: left(std::move(left)), right(std::move(right)) {}
|
||||
int value() const override { return left->value() * right->value(); }
|
||||
unique_virtual_ptr<const Node> left, right;
|
||||
};
|
||||
|
||||
#include <iostream>
|
||||
|
||||
BOOST_OPENMETHOD(postfix, (virtual_ptr<const Node> node, std::ostream& os), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Variable> var, std::ostream& os), void) {
|
||||
os << var->v;
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Plus> plus, std::ostream& os), void) {
|
||||
postfix(plus->left, os);
|
||||
os << ' ';
|
||||
postfix(plus->right, os);
|
||||
os << " +";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Times> times, std::ostream& os), void) {
|
||||
postfix(times->left, os);
|
||||
os << ' ';
|
||||
postfix(times->right, os);
|
||||
os << " *";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Node, Variable, Plus, Times);
|
||||
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
|
||||
auto a = std::make_unique<Variable>(2);
|
||||
auto b = std::make_unique<Variable>(3);
|
||||
auto c = std::make_unique<Variable>(4);
|
||||
auto d = make_unique_virtual<Plus>(std::move(a), std::move(b));
|
||||
auto e = make_unique_virtual<Times>(std::move(d), std::move(c));
|
||||
|
||||
postfix(e, std::cout);
|
||||
std::cout << " = " << e->value() << "\n"; // 2 3 + 4 * = 20
|
||||
}
|
||||
// end::content[]
|
||||
39
doc/modules/ROOT/examples/ast_virtual_function.cpp
Normal file
39
doc/modules/ROOT/examples/ast_virtual_function.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
// tag::content[]
|
||||
#include <iostream>
|
||||
|
||||
struct Node {
|
||||
virtual ~Node() {}
|
||||
virtual int value() const = 0;
|
||||
};
|
||||
|
||||
struct Variable : Node {
|
||||
Variable(int value) : v(value) {}
|
||||
int value() const override { return v; }
|
||||
int v;
|
||||
};
|
||||
|
||||
struct Plus : Node {
|
||||
Plus(const Node& left, const Node& right) : left(left), right(right) {}
|
||||
int value() const override { return left.value() + right.value(); }
|
||||
const Node& left; const Node& right;
|
||||
};
|
||||
|
||||
struct Times : Node {
|
||||
Times(const Node& left, const Node& right) : left(left), right(right) {}
|
||||
int value() const override { return left.value() * right.value(); }
|
||||
const Node& left; const Node& right;
|
||||
};
|
||||
|
||||
int main() {
|
||||
Variable a{2}, b{3}, c{4};
|
||||
Plus d{a, b}; Times e{d, c};
|
||||
std::cout << e.value() << "\n"; // 20
|
||||
}
|
||||
// end::content[]
|
||||
52
doc/modules/ROOT/examples/ast_virtual_function_2.cpp
Normal file
52
doc/modules/ROOT/examples/ast_virtual_function_2.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
// tag::all[]
|
||||
#include <iostream>
|
||||
|
||||
struct Node {
|
||||
virtual ~Node() {}
|
||||
virtual int value() const = 0;
|
||||
virtual void postfix(std::ostream& os) const = 0;
|
||||
};
|
||||
|
||||
struct Variable : Node {
|
||||
Variable(int value) : v(value) {}
|
||||
int value() const override { return v; }
|
||||
virtual void postfix(std::ostream& os) const override { os << v; }
|
||||
int v;
|
||||
};
|
||||
|
||||
struct Plus : Node {
|
||||
Plus(const Node& left, const Node& right) : left(left), right(right) {}
|
||||
int value() const override { return left.value() + right.value(); }
|
||||
void postfix(std::ostream& os) const override {
|
||||
left.postfix(os); os << ' '; right.postfix(os); os << " +";
|
||||
}
|
||||
const Node& left; const Node& right;
|
||||
};
|
||||
|
||||
struct Times : Node {
|
||||
Times(const Node& left, const Node& right) : left(left), right(right) {}
|
||||
int value() const override { return left.value() * right.value(); }
|
||||
void postfix(std::ostream& os) const override {
|
||||
left.postfix(os); os << ' '; right.postfix(os); os << " *";
|
||||
}
|
||||
const Node& left; const Node& right;
|
||||
};
|
||||
|
||||
int main() {
|
||||
Variable a{2}, b{3}, c{4};
|
||||
Plus d{a, b}; Times e{d, c};
|
||||
e.postfix(std::cout);
|
||||
std::cout << " = " << e.value() << "\n"; // 2 3 + 4 * = 20
|
||||
}
|
||||
// end::all[]
|
||||
|
||||
void call_virtual_function(const Node& node, std::ostream& os) {
|
||||
node.postfix(os);
|
||||
}
|
||||
75
doc/modules/ROOT/examples/ast_virtual_ptr.cpp
Normal file
75
doc/modules/ROOT/examples/ast_virtual_ptr.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
// tag::content[]
|
||||
#include <boost/openmethod.hpp>
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
struct Node {
|
||||
virtual ~Node() {}
|
||||
virtual int value() const = 0;
|
||||
};
|
||||
|
||||
struct Variable : Node {
|
||||
Variable(int value) : v(value) {}
|
||||
int value() const override { return v; }
|
||||
int v;
|
||||
};
|
||||
|
||||
struct Plus : Node {
|
||||
Plus(virtual_ptr<const Node> left, virtual_ptr<const Node> right)
|
||||
: left(left), right(right) {}
|
||||
int value() const override { return left->value() + right->value(); }
|
||||
virtual_ptr<const Node> left, right;
|
||||
};
|
||||
|
||||
struct Times : Node {
|
||||
Times(virtual_ptr<const Node> left, virtual_ptr<const Node> right)
|
||||
: left(left), right(right) {}
|
||||
int value() const override { return left->value() * right->value(); }
|
||||
virtual_ptr<const Node> left, right;
|
||||
};
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
BOOST_OPENMETHOD(postfix, (virtual_ptr<const Node> node, std::ostream& os), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Variable> var, std::ostream& os), void) {
|
||||
os << var->v;
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Plus> plus, std::ostream& os), void) {
|
||||
postfix(plus->left, os);
|
||||
os << ' ';
|
||||
postfix(plus->right, os);
|
||||
os << " +";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Times> times, std::ostream& os), void) {
|
||||
postfix(times->left, os);
|
||||
os << ' ';
|
||||
postfix(times->right, os);
|
||||
os << " *";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Node, Variable, Plus, Times);
|
||||
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
Variable a{2}, b{3}, c{4};
|
||||
Plus d{a, b}; Times e{d, c};
|
||||
postfix(e, std::cout);
|
||||
std::cout << " = " << e.value() << "\n"; // 2 3 + 4 * = 20
|
||||
}
|
||||
// end::content[]
|
||||
@@ -7,7 +7,9 @@
|
||||
// Example for Wikipedia
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
class Thing {
|
||||
public:
|
||||
@@ -24,31 +26,32 @@ BOOST_OPENMETHOD_CLASSES(Thing, Spaceship, Asteroid);
|
||||
BOOST_OPENMETHOD(collideWith, (virtual_ptr<Thing>, virtual_ptr<Thing>), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
collideWith, (virtual_ptr<Thing> left, virtual_ptr<Thing> right), void) {
|
||||
collideWith, (virtual_ptr<Thing> /*left*/, virtual_ptr<Thing> /*right*/),
|
||||
void) {
|
||||
// default collision handling
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
collideWith, (virtual_ptr<Asteroid> left, virtual_ptr<Asteroid> right),
|
||||
void) {
|
||||
collideWith,
|
||||
(virtual_ptr<Asteroid> /*left*/, virtual_ptr<Asteroid> /*right*/), void) {
|
||||
// handle Asteroid-Asteroid collision
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
collideWith, (virtual_ptr<Asteroid> left, virtual_ptr<Spaceship> right),
|
||||
void) {
|
||||
collideWith,
|
||||
(virtual_ptr<Asteroid> /*left*/, virtual_ptr<Spaceship> /*right*/), void) {
|
||||
// handle Asteroid-Spaceship collision
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
collideWith, (virtual_ptr<Spaceship> left, virtual_ptr<Asteroid> right),
|
||||
void) {
|
||||
collideWith,
|
||||
(virtual_ptr<Spaceship> /*left*/, virtual_ptr<Asteroid> /*right*/), void) {
|
||||
// handle Spaceship-Asteroid collision
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
collideWith, (virtual_ptr<Spaceship> left, virtual_ptr<Spaceship> right),
|
||||
void) {
|
||||
collideWith,
|
||||
(virtual_ptr<Spaceship> /*left*/, virtual_ptr<Spaceship> /*right*/), void) {
|
||||
// handle Spaceship-Spaceship collision
|
||||
}
|
||||
|
||||
99
doc/modules/ROOT/examples/core_api/1/core_api.cpp
Normal file
99
doc/modules/ROOT/examples/core_api/1/core_api.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
#include <boost/openmethod/core.hpp>
|
||||
|
||||
struct Node {
|
||||
virtual ~Node() {
|
||||
}
|
||||
virtual int value() const = 0;
|
||||
};
|
||||
|
||||
struct Variable : Node {
|
||||
Variable(int value) : v(value) {
|
||||
}
|
||||
int value() const override {
|
||||
return v;
|
||||
}
|
||||
int v;
|
||||
};
|
||||
|
||||
struct Plus : Node {
|
||||
Plus(const Node& left, const Node& right) : left(left), right(right) {
|
||||
}
|
||||
int value() const override {
|
||||
return left.value() + right.value();
|
||||
}
|
||||
const Node& left;
|
||||
const Node& right;
|
||||
};
|
||||
|
||||
struct Times : Node {
|
||||
Times(const Node& left, const Node& right) : left(left), right(right) {
|
||||
}
|
||||
int value() const override {
|
||||
return left.value() * right.value();
|
||||
}
|
||||
const Node& left;
|
||||
const Node& right;
|
||||
};
|
||||
|
||||
using namespace boost::openmethod;
|
||||
|
||||
// tag::method[]
|
||||
#include <boost/openmethod/macros.hpp>
|
||||
|
||||
struct BOOST_OPENMETHOD_ID(postfix);
|
||||
|
||||
using postfix = method<
|
||||
BOOST_OPENMETHOD_ID(postfix),
|
||||
void(virtual_ptr<const Node> node, std::ostream& os)>;
|
||||
// end::method[]
|
||||
|
||||
// tag::variable_overrider[]
|
||||
auto postfix_variable(virtual_ptr<const Variable> node, std::ostream& os) {
|
||||
os << node->v;
|
||||
}
|
||||
|
||||
static postfix::override<postfix_variable> override_postfix_variable;
|
||||
// end::variable_overrider[]
|
||||
|
||||
// tag::binary_overriders[]
|
||||
#include <boost/openmethod/macros.hpp>
|
||||
|
||||
auto postfix_plus(virtual_ptr<const Plus> node, std::ostream& os) {
|
||||
postfix::fn(node->left, os);
|
||||
os << ' ';
|
||||
postfix::fn(node->right, os);
|
||||
os << " +";
|
||||
}
|
||||
|
||||
auto postfix_times(virtual_ptr<const Times> node, std::ostream& os) {
|
||||
postfix::fn(node->left, os);
|
||||
os << ' ';
|
||||
postfix::fn(node->right, os);
|
||||
os << " *";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_REGISTER(postfix::override<postfix_plus, postfix_times>);
|
||||
// end::binary_overriders[]
|
||||
|
||||
// tag::use_classes[]
|
||||
BOOST_OPENMETHOD_REGISTER(use_classes<Node, Variable, Plus, Times>);
|
||||
// end::use_classes[]
|
||||
|
||||
// tag::main[]
|
||||
auto main() -> int {
|
||||
boost::openmethod::initialize();
|
||||
Variable a{2}, b{3}, c{4};
|
||||
Plus d{a, b};
|
||||
Times e{d, c};
|
||||
postfix::fn(e, std::cout);
|
||||
std::cout << " = " << e.value() << "\n"; // 2 3 + 4 * = 20
|
||||
}
|
||||
// end::main[]
|
||||
77
doc/modules/ROOT/examples/core_api/2/core_api.cpp
Normal file
77
doc/modules/ROOT/examples/core_api/2/core_api.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// tag::classes[]
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
struct Node {
|
||||
virtual ~Node() {}
|
||||
virtual int value() const = 0;
|
||||
};
|
||||
|
||||
struct Variable : Node {
|
||||
Variable(int value) : v(value) {}
|
||||
int value() const override { return v; }
|
||||
int v;
|
||||
};
|
||||
|
||||
template<typename Op>
|
||||
struct BinaryOp : Node {
|
||||
BinaryOp(const Node& left, const Node& right) : left(left), right(right) {}
|
||||
int value() const override { return Op()(left.value(), right.value()); }
|
||||
const Node& left;
|
||||
const Node& right;
|
||||
};
|
||||
// end::classes[]
|
||||
|
||||
using namespace boost::openmethod;
|
||||
|
||||
// tag::method[]
|
||||
BOOST_OPENMETHOD(
|
||||
postfix, (virtual_ptr<const Node> node, std::ostream& os), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Variable> var, std::ostream& os), void) {
|
||||
os << var->v;
|
||||
}
|
||||
// end::method[]
|
||||
|
||||
// tag::postfix_binary[]
|
||||
template<class BinaryOp, char Op>
|
||||
auto postfix_binary(virtual_ptr<const BinaryOp> node, std::ostream& os) {
|
||||
postfix(node->left, os);
|
||||
os << ' ';
|
||||
postfix(node->right, os);
|
||||
os << " " << Op;
|
||||
}
|
||||
// end::postfix_binary[]
|
||||
|
||||
// tag::add_postfix_binary[]
|
||||
BOOST_OPENMETHOD_TYPE(
|
||||
postfix, (virtual_ptr<const Node> node, std::ostream& os), void)::
|
||||
override<
|
||||
postfix_binary<BinaryOp<std::plus<int>>, '+'>,
|
||||
postfix_binary<
|
||||
BinaryOp<std::multiplies<int>>, '*'>> add_binary_overriders;
|
||||
// end::add_postfix_binary[]
|
||||
|
||||
// tag::main[]
|
||||
BOOST_OPENMETHOD_CLASSES(
|
||||
Node, Variable, BinaryOp<std::plus<int>>, BinaryOp<std::multiplies<int>>);
|
||||
|
||||
auto main() -> int {
|
||||
boost::openmethod::initialize();
|
||||
Variable a{2}, b{3}, c{4};
|
||||
BinaryOp<std::plus<int>> d{a, b};
|
||||
BinaryOp<std::multiplies<int>> e{d, c};
|
||||
postfix(e, std::cout);
|
||||
std::cout << " = " << e.value() << "\n"; // 2 3 + 4 * = 20
|
||||
}
|
||||
// end::main[]
|
||||
@@ -3,6 +3,10 @@
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4312)
|
||||
#endif
|
||||
|
||||
struct Animal {
|
||||
Animal(unsigned type) : type(type) {
|
||||
}
|
||||
@@ -27,59 +31,63 @@ struct Dog : Animal {
|
||||
static constexpr unsigned static_type = 3;
|
||||
};
|
||||
|
||||
#include <boost/openmethod/policies/basic_policy.hpp>
|
||||
#include <boost/openmethod/preamble.hpp>
|
||||
#include <boost/openmethod/policies/vptr_vector.hpp>
|
||||
|
||||
// tag::facet[]
|
||||
// tag::policy[]
|
||||
namespace bom = boost::openmethod;
|
||||
|
||||
struct custom_rtti : bom::policies::rtti {
|
||||
template<class T>
|
||||
static constexpr bool is_polymorphic = std::is_base_of_v<Animal, T>;
|
||||
template<class Registry>
|
||||
struct fn : bom::policies::rtti::defaults {
|
||||
template<class T>
|
||||
static constexpr bool is_polymorphic = std::is_base_of_v<Animal, T>;
|
||||
|
||||
template<typename T>
|
||||
static auto static_type() -> bom::type_id {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return T::static_type;
|
||||
} else {
|
||||
return 0;
|
||||
template<typename T>
|
||||
static auto static_type() -> bom::type_id {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return reinterpret_cast<bom::type_id>(T::static_type);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) -> bom::type_id {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return obj.type;
|
||||
} else {
|
||||
return 0;
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) -> bom::type_id {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return reinterpret_cast<bom::type_id>(obj.type);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
// end::facet[]
|
||||
|
||||
// tag::policy[]
|
||||
struct custom_policy : bom::policies::basic_policy<
|
||||
custom_policy, custom_rtti,
|
||||
bom::policies::vptr_vector<custom_policy>> {};
|
||||
|
||||
#define BOOST_OPENMETHOD_DEFAULT_POLICY custom_policy
|
||||
// end::policy[]
|
||||
|
||||
// tag::registry[]
|
||||
struct custom_registry
|
||||
: bom::registry<custom_rtti, bom::policies::vptr_vector> {};
|
||||
|
||||
#define BOOST_OPENMETHOD_DEFAULT_REGISTRY custom_registry
|
||||
// end::registry[]
|
||||
|
||||
// tag::example[]
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
BOOST_OPENMETHOD(poke, (std::ostream&, virtual_ptr<Animal>), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
poke, (std::ostream & os, virtual_ptr<Cat> cat), void) {
|
||||
poke, (std::ostream & os, virtual_ptr<Cat> /*cat*/), void) {
|
||||
os << "hiss";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
poke, (std::ostream & os, virtual_ptr<Dog> dog), void) {
|
||||
poke, (std::ostream & os, virtual_ptr<Dog> /*dog*/), void) {
|
||||
os << "bark";
|
||||
}
|
||||
|
||||
124
doc/modules/ROOT/examples/custom_rtti/1/custom_rtti.cpp
Normal file
124
doc/modules/ROOT/examples/custom_rtti/1/custom_rtti.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
// tag::classes[]
|
||||
struct Node {
|
||||
virtual ~Node() {}
|
||||
virtual int value() const = 0;
|
||||
// our custom RTTI:
|
||||
Node(unsigned type) : type(type) {}
|
||||
unsigned type;
|
||||
static constexpr unsigned static_type = 1;
|
||||
};
|
||||
|
||||
struct Variable : Node {
|
||||
static constexpr unsigned static_type = 2;
|
||||
Variable(int value) : Node(static_type), v(value) {}
|
||||
int value() const override { return v; }
|
||||
int v;
|
||||
};
|
||||
|
||||
struct Plus : Node {
|
||||
static constexpr unsigned static_type = 3;
|
||||
Plus(const Node& left, const Node& right)
|
||||
: Node(static_type), left(left), right(right) {}
|
||||
int value() const override { return left.value() + right.value(); }
|
||||
const Node& left; const Node& right;
|
||||
};
|
||||
|
||||
struct Times : Node {
|
||||
static constexpr unsigned static_type = 4;
|
||||
Times(const Node& left, const Node& right)
|
||||
: Node(static_type), left(left), right(right) {}
|
||||
int value() const override { return left.value() * right.value(); }
|
||||
const Node& left; const Node& right;
|
||||
};
|
||||
// end::classes[]
|
||||
|
||||
// tag::policy[]
|
||||
#include <boost/openmethod/preamble.hpp>
|
||||
#include <boost/openmethod/policies/vptr_vector.hpp>
|
||||
|
||||
struct custom_rtti : boost::openmethod::policies::rtti {
|
||||
template<class Registry>
|
||||
struct fn : defaults {
|
||||
template<class T>
|
||||
static constexpr bool is_polymorphic = std::is_base_of_v<Node, T>;
|
||||
|
||||
using type_id = boost::openmethod::type_id; // for brevity
|
||||
|
||||
template<typename T>
|
||||
static auto static_type() {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return reinterpret_cast<type_id>(T::static_type);
|
||||
} else {
|
||||
return reinterpret_cast<type_id>(0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return reinterpret_cast<type_id>(obj.type);
|
||||
} else {
|
||||
return reinterpret_cast<type_id>(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
// end::policy[]
|
||||
|
||||
// tag::registry[]
|
||||
struct custom_registry : boost::openmethod::registry<
|
||||
custom_rtti, boost::openmethod::policies::vptr_vector> {};
|
||||
|
||||
#define BOOST_OPENMETHOD_DEFAULT_REGISTRY custom_registry
|
||||
// end::registry[]
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
BOOST_OPENMETHOD(postfix, (virtual_ptr<const Node> node, std::ostream& os), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Variable> var, std::ostream& os), void) {
|
||||
os << var->v;
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Plus> plus, std::ostream& os), void) {
|
||||
postfix(plus->left, os);
|
||||
os << ' ';
|
||||
postfix(plus->right, os);
|
||||
os << " +";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
postfix, (virtual_ptr<const Times> times, std::ostream& os), void) {
|
||||
postfix(times->left, os);
|
||||
os << ' ';
|
||||
postfix(times->right, os);
|
||||
os << " *";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Node, Variable, Plus, Times);
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
Variable a{2}, b{3}, c{4};
|
||||
Plus d{a, b}; Times e{d, c};
|
||||
postfix(e, std::cout);
|
||||
std::cout << " = " << e.value() << "\n"; // 2 3 + 4 * = 20
|
||||
}
|
||||
// end::content[]
|
||||
|
||||
void call_via_ref(const Node& node, std::ostream& os) {
|
||||
postfix(node, os);
|
||||
}
|
||||
118
doc/modules/ROOT/examples/custom_rtti/2/custom_rtti.cpp
Normal file
118
doc/modules/ROOT/examples/custom_rtti/2/custom_rtti.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// clang-format off
|
||||
|
||||
// tag::classes[]
|
||||
struct Node {
|
||||
Node(unsigned type) : type(type) {}
|
||||
unsigned type;
|
||||
static unsigned last_type;
|
||||
static unsigned static_type;
|
||||
};
|
||||
|
||||
struct Variable : Node {
|
||||
static unsigned static_type;
|
||||
Variable(int value) : Node(static_type), v(value) {}
|
||||
int v;
|
||||
};
|
||||
|
||||
struct Plus : Node {
|
||||
static unsigned static_type;
|
||||
Plus(const Node& left, const Node& right)
|
||||
: Node(static_type), left(left), right(right) {}
|
||||
const Node& left; const Node& right;
|
||||
};
|
||||
|
||||
struct Times : Node {
|
||||
static unsigned static_type;
|
||||
Times(const Node& left, const Node& right)
|
||||
: Node(static_type), left(left), right(right) {}
|
||||
const Node& left; const Node& right;
|
||||
};
|
||||
// end::classes[]
|
||||
|
||||
// tag::policy[]
|
||||
#include <boost/openmethod/preamble.hpp>
|
||||
#include <boost/openmethod/policies/vptr_vector.hpp>
|
||||
|
||||
// note: vvvvvvvvvvvvvvvv
|
||||
struct custom_rtti : boost::openmethod::policies::deferred_static_rtti {
|
||||
template<class Registry>
|
||||
struct fn : defaults {
|
||||
template<class T>
|
||||
static constexpr bool is_polymorphic = std::is_base_of_v<Node, T>;
|
||||
|
||||
using type_id = boost::openmethod::type_id; // for brevity
|
||||
|
||||
template<typename T>
|
||||
static auto static_type() {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return reinterpret_cast<type_id>(T::static_type);
|
||||
} else {
|
||||
return reinterpret_cast<type_id>(0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return reinterpret_cast<type_id>(obj.type);
|
||||
} else {
|
||||
return reinterpret_cast<type_id>(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
// end::policy[]
|
||||
|
||||
// tag::registry[]
|
||||
struct custom_registry : boost::openmethod::registry<
|
||||
custom_rtti, boost::openmethod::policies::vptr_vector> {};
|
||||
|
||||
#define BOOST_OPENMETHOD_DEFAULT_REGISTRY custom_registry
|
||||
// end::registry[]
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
BOOST_OPENMETHOD(value, (virtual_ptr<const Node>), int);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Plus> node), int) {
|
||||
return value(node->left) + value(node->right);
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Times> node), int) {
|
||||
return value(node->left) * value(node->right);
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr<const Variable> node), int) {
|
||||
return node->v;
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Node, Variable, Plus, Times);
|
||||
|
||||
// tag::type_ids[]
|
||||
unsigned Node::last_type = 0;
|
||||
unsigned Node::static_type = ++Node::last_type;
|
||||
unsigned Variable::static_type = ++Node::last_type;
|
||||
unsigned Plus::static_type = ++Node::last_type;
|
||||
unsigned Times::static_type = ++Node::last_type;
|
||||
// end::type_ids[]
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
Variable a{2}, b{3}, c{4};
|
||||
Plus d{a, b}; Times e{d, c};
|
||||
std::cout << value(e) << "\n"; // 2 3 + 4 * = 20
|
||||
}
|
||||
// end::content[]
|
||||
|
||||
auto call_via_ref(const Node& node, std::ostream& os) {
|
||||
return value(node);
|
||||
}
|
||||
@@ -8,7 +8,9 @@
|
||||
#include <variant>
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
struct Animal {
|
||||
virtual ~Animal() = default;
|
||||
@@ -22,7 +24,7 @@ BOOST_OPENMETHOD_CLASSES(Animal, Cat, Dog);
|
||||
BOOST_OPENMETHOD(trick, (std::ostream&, virtual_ptr<Animal>), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
trick, (std::ostream & os, virtual_ptr<Dog> dog), void) {
|
||||
trick, (std::ostream & os, virtual_ptr<Dog> /*dog*/), void) {
|
||||
os << "spin\n";
|
||||
}
|
||||
|
||||
@@ -30,12 +32,11 @@ auto main() -> int {
|
||||
namespace bom = boost::openmethod;
|
||||
bom::initialize();
|
||||
|
||||
bom::default_policy::set_error_handler(
|
||||
[](const bom::default_policy::error_variant& error) {
|
||||
if (std::holds_alternative<bom::not_implemented_error>(error)) {
|
||||
throw std::runtime_error("not implemented");
|
||||
}
|
||||
});
|
||||
bom::default_registry::error_handler::set([](const auto& error) {
|
||||
if (std::holds_alternative<bom::no_overrider>(error)) {
|
||||
throw std::runtime_error("not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
Cat felix;
|
||||
Dog hector, snoopy;
|
||||
@@ -3,6 +3,10 @@
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4312)
|
||||
#endif
|
||||
|
||||
// tag::classes[]
|
||||
struct custom_type_info {
|
||||
static unsigned last;
|
||||
@@ -72,65 +76,71 @@ struct Dog : virtual Animal {
|
||||
static custom_type_info type_info;
|
||||
};
|
||||
|
||||
#include <boost/openmethod/policies/basic_policy.hpp>
|
||||
#include <boost/openmethod/preamble.hpp>
|
||||
#include <boost/openmethod/policies/vptr_vector.hpp>
|
||||
|
||||
namespace bom = boost::openmethod;
|
||||
|
||||
struct custom_rtti : bom::policies::rtti {
|
||||
template<typename T>
|
||||
static auto static_type() -> bom::type_id {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
return T::type_info.id;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// tag::registry[]
|
||||
struct custom_rtti : bom::policies::deferred_static_rtti {
|
||||
template<class Registry>
|
||||
struct fn : defaults {
|
||||
template<class T>
|
||||
static constexpr bool is_polymorphic = std::is_base_of_v<Animal, T>;
|
||||
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) -> bom::type_id {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
return obj.type;
|
||||
} else {
|
||||
return 0;
|
||||
template<typename T>
|
||||
static auto static_type() -> bom::type_id {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
return reinterpret_cast<bom::type_id>(T::type_info.id);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tag::dynamic_cast_ref[]
|
||||
// to support virtual inheritance:
|
||||
template<typename Derived, typename Base>
|
||||
static auto dynamic_cast_ref(Base&& obj) -> Derived {
|
||||
using base_type = std::remove_reference_t<Base>;
|
||||
if constexpr (std::is_base_of_v<Animal, base_type>) {
|
||||
return *obj.template cast<std::remove_reference_t<Derived>>();
|
||||
} else {
|
||||
abort(); // not supported
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) -> bom::type_id {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
return reinterpret_cast<bom::type_id>(obj.type);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
// end::dynamic_cast_ref[]
|
||||
|
||||
// to support virtual inheritance:
|
||||
template<typename Derived, typename Base>
|
||||
static auto dynamic_cast_ref(Base&& obj) -> Derived {
|
||||
using base_type = std::remove_reference_t<Base>;
|
||||
if constexpr (std::is_base_of_v<Animal, base_type>) {
|
||||
return *obj.template cast<std::remove_reference_t<Derived>>();
|
||||
} else {
|
||||
abort(); // not supported
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct custom_policy
|
||||
: bom::policies::basic_policy<
|
||||
custom_policy, custom_rtti, bom::policies::deferred_static_rtti,
|
||||
bom::policies::vptr_vector<custom_policy>> {};
|
||||
struct custom_registry : bom::registry<custom_rtti, bom::policies::vptr_vector> {
|
||||
};
|
||||
// end::registry[]
|
||||
|
||||
#define BOOST_OPENMETHOD_DEFAULT_POLICY custom_policy
|
||||
#define BOOST_OPENMETHOD_DEFAULT_REGISTRY custom_registry
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
BOOST_OPENMETHOD(poke, (std::ostream&, virtual_ptr<Animal>), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
poke, (std::ostream & os, virtual_ptr<Cat> cat), void) {
|
||||
poke, (std::ostream & os, virtual_ptr<Cat> /*cat*/), void) {
|
||||
os << "hiss";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
poke, (std::ostream & os, virtual_ptr<Dog> dog), void) {
|
||||
poke, (std::ostream & os, virtual_ptr<Dog> /*dog*/), void) {
|
||||
os << "bark";
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <string>
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
#ifdef FRIEND_ALL
|
||||
|
||||
// tag::friend_all[]
|
||||
@@ -37,7 +39,7 @@ class Animal {
|
||||
class Cat;
|
||||
class Dog;
|
||||
|
||||
template<typename> struct BOOST_OPENMETHOD_OVERRIDERS(poke);
|
||||
template<typename...> struct BOOST_OPENMETHOD_OVERRIDERS(poke);
|
||||
|
||||
class Animal {
|
||||
// ...
|
||||
@@ -82,7 +84,7 @@ BOOST_OPENMETHOD_OVERRIDE(
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Animal, Cat, Dog);
|
||||
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
auto main() -> int {
|
||||
boost::openmethod::initialize();
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <string>
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
#ifdef FRIEND_ALL
|
||||
|
||||
// tag::friend_all[]
|
||||
@@ -41,7 +43,7 @@ BOOST_OPENMETHOD(poke, (std::ostream&, virtual_ptr<Animal>), void);
|
||||
namespace pets {
|
||||
struct Cat;
|
||||
struct Dog;
|
||||
template<typename> struct BOOST_OPENMETHOD_OVERRIDERS(poke);
|
||||
template<typename...> struct BOOST_OPENMETHOD_OVERRIDERS(poke);
|
||||
} // namespace pets
|
||||
|
||||
namespace core {
|
||||
@@ -96,7 +98,7 @@ BOOST_OPENMETHOD_CLASSES(core::Animal, Cat, Dog);
|
||||
} // namespace pets
|
||||
// end::friend[]
|
||||
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
auto main() -> int {
|
||||
boost::openmethod::initialize();
|
||||
@@ -15,7 +15,8 @@ struct Animal {
|
||||
virtual ~Animal() = default;
|
||||
};
|
||||
|
||||
BOOST_OPENMETHOD(poke, (std::ostream&, virtual_ptr<Animal>), void);
|
||||
BOOST_OPENMETHOD(
|
||||
poke, (std::ostream&, boost::openmethod::virtual_ptr<Animal>), void);
|
||||
|
||||
} // namespace animals
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "cat.hpp"
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
namespace felines {
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(animals::Animal, Cat, Cheetah);
|
||||
@@ -8,7 +8,7 @@ namespace canines {
|
||||
BOOST_OPENMETHOD_CLASSES(animals::Animal, Dog);
|
||||
|
||||
BOOST_OPENMETHOD_DEFINE_OVERRIDER(
|
||||
poke, (std::ostream & os, virtual_ptr<Dog> dog), void) {
|
||||
poke, (std::ostream & os, boost::openmethod::virtual_ptr<Dog> dog), void) {
|
||||
os << dog->name << " barks";
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ struct Dog : animals::Animal {
|
||||
};
|
||||
|
||||
BOOST_OPENMETHOD_DECLARE_OVERRIDER(
|
||||
poke, (std::ostream & os, virtual_ptr<Dog> dog), void);
|
||||
poke, (std::ostream & os, boost::openmethod::virtual_ptr<Dog> dog), void);
|
||||
|
||||
} // namespace canines
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include <iostream>
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
#include "animal.hpp"
|
||||
#include "cat.hpp"
|
||||
#include "dog.hpp"
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
struct Bulldog : canines::Dog {
|
||||
using Dog::Dog;
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <iostream>
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
#include "animal.hpp"
|
||||
#include "cat.hpp"
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <iostream>
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
#include "animal.hpp"
|
||||
#include "cat.hpp"
|
||||
@@ -31,6 +31,8 @@ struct Bulldog : Dog {
|
||||
#include <iostream>
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
BOOST_OPENMETHOD(
|
||||
poke, // method name
|
||||
(std::ostream&, virtual_ptr<Animal>), // method signature
|
||||
@@ -77,7 +79,7 @@ BOOST_OPENMETHOD_OVERRIDE(
|
||||
// Add definitions for specific pairs of animals.
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
encounter,
|
||||
(std::ostream & os, virtual_ptr<Dog> dog1, virtual_ptr<Dog> dog2), void) {
|
||||
(std::ostream & os, virtual_ptr<Dog> /*dog1*/, virtual_ptr<Dog> /*dog2*/), void) {
|
||||
os << "Both wag tails";
|
||||
}
|
||||
|
||||
@@ -95,7 +97,7 @@ BOOST_OPENMETHOD_OVERRIDE(
|
||||
// end::multi[]
|
||||
|
||||
// tag::main[]
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
// only needed in the file that calls boost::openmethod::initialize()
|
||||
|
||||
auto main() -> int {
|
||||
42
doc/modules/ROOT/examples/inplace_vptr.cpp
Normal file
42
doc/modules/ROOT/examples/inplace_vptr.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/inplace_vptr.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
using namespace boost::openmethod;
|
||||
|
||||
struct Animal : inplace_vptr_base<Animal> {};
|
||||
|
||||
struct Cat : Animal, inplace_vptr_derived<Cat, Animal> {};
|
||||
|
||||
struct Dog : Animal, inplace_vptr_derived<Dog, Animal> {};
|
||||
|
||||
BOOST_OPENMETHOD(
|
||||
poke, (virtual_<Animal&> animal, std::ostream& os), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(poke, (Cat&, std::ostream& os), void) {
|
||||
os << "hiss\n";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(poke, (Dog&, std::ostream& os), void) {
|
||||
os << "bark\n";
|
||||
}
|
||||
|
||||
int main() {
|
||||
initialize();
|
||||
|
||||
std::unique_ptr<Animal> a = std::make_unique<Cat>();
|
||||
std::unique_ptr<Animal> b = std::make_unique<Dog>();
|
||||
|
||||
poke(*a, std::cout); // hiss
|
||||
poke(*b, std::cout); // bark
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <typeinfo>
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/shared_ptr.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
#include <boost/openmethod/interop/std_shared_ptr.hpp>
|
||||
|
||||
using std::make_shared;
|
||||
using std::shared_ptr;
|
||||
@@ -18,6 +18,7 @@ using std::string;
|
||||
|
||||
using boost::openmethod::make_shared_virtual;
|
||||
using boost::openmethod::shared_virtual_ptr;
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
struct matrix {
|
||||
virtual ~matrix() {
|
||||
@@ -27,13 +28,13 @@ struct matrix {
|
||||
};
|
||||
|
||||
struct dense_matrix : matrix {
|
||||
virtual auto at(int row, int col) const -> double {
|
||||
virtual auto at(int /*row*/, int /*col*/) const -> double {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct diagonal_matrix : matrix {
|
||||
virtual auto at(int row, int col) const -> double {
|
||||
virtual auto at(int /*row*/, int /*col*/) const -> double {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@@ -42,13 +43,12 @@ BOOST_OPENMETHOD_CLASSES(matrix, dense_matrix, diagonal_matrix);
|
||||
|
||||
BOOST_OPENMETHOD(to_json, (virtual_ptr<const matrix>), string);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
to_json, (virtual_ptr<const dense_matrix> m), string) {
|
||||
BOOST_OPENMETHOD_OVERRIDE(to_json, (virtual_ptr<const dense_matrix>), string) {
|
||||
return "json for dense matrix...";
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
to_json, (virtual_ptr<const diagonal_matrix> m), string) {
|
||||
to_json, (virtual_ptr<const diagonal_matrix>), string) {
|
||||
return "json for diagonal matrix...";
|
||||
}
|
||||
|
||||
@@ -62,7 +62,8 @@ BOOST_OPENMETHOD(
|
||||
// catch-all matrix * matrix -> dense_matrix
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
times,
|
||||
(shared_virtual_ptr<const matrix> a, shared_virtual_ptr<const matrix> b),
|
||||
(shared_virtual_ptr<const matrix> /*a*/,
|
||||
shared_virtual_ptr<const matrix> /*b*/),
|
||||
shared_virtual_ptr<const dense_matrix>) {
|
||||
return make_shared<const dense_matrix>();
|
||||
}
|
||||
@@ -70,8 +71,8 @@ BOOST_OPENMETHOD_OVERRIDE(
|
||||
// diagonal_matrix * diagonal_matrix -> diagonal_matrix
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
times,
|
||||
(shared_virtual_ptr<const diagonal_matrix> a,
|
||||
shared_virtual_ptr<const diagonal_matrix> b),
|
||||
(shared_virtual_ptr<const diagonal_matrix> /*a*/,
|
||||
shared_virtual_ptr<const diagonal_matrix> /*b*/),
|
||||
shared_virtual_ptr<const diagonal_matrix>) {
|
||||
return make_shared_virtual<diagonal_matrix>();
|
||||
}
|
||||
@@ -90,13 +91,13 @@ BOOST_OPENMETHOD(
|
||||
|
||||
// catch-all matrix * scalar -> dense_matrix
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
times, (double a, shared_virtual_ptr<const matrix> b),
|
||||
times, (double /*a*/, shared_virtual_ptr<const matrix> /*b*/),
|
||||
shared_virtual_ptr<const dense_matrix>) {
|
||||
return make_shared_virtual<dense_matrix>();
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
times, (double a, shared_virtual_ptr<const diagonal_matrix> b),
|
||||
times, (double /*a*/, shared_virtual_ptr<const diagonal_matrix> /*b*/),
|
||||
shared_virtual_ptr<const diagonal_matrix>) {
|
||||
return make_shared_virtual<diagonal_matrix>();
|
||||
}
|
||||
@@ -130,7 +131,7 @@ auto main() -> int {
|
||||
shared_ptr<const matrix> b = make_shared<diagonal_matrix>();
|
||||
double s = 1;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#ifdef BOOST_CLANG
|
||||
#pragma clang diagnostic ignored "-Wpotentially-evaluated-expression"
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
#include <boost/openmethod/compiler.hpp>
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
using boost::openmethod::virtual_ptr;
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -37,8 +39,7 @@ BOOST_OPENMETHOD(
|
||||
inspect, (virtual_ptr<const Vehicle>, virtual_ptr<const Inspector>), void);
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
inspect, (virtual_ptr<const Vehicle> v, virtual_ptr<const Inspector> i),
|
||||
void) {
|
||||
inspect, (virtual_ptr<const Vehicle>, virtual_ptr<const Inspector>), void) {
|
||||
cout << "Inspect vehicle.\n";
|
||||
}
|
||||
|
||||
18
doc/modules/ROOT/examples/rolex/1/employee.cpp
Normal file
18
doc/modules/ROOT/examples/rolex/1/employee.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// tag::content[]
|
||||
// employee.cpp
|
||||
|
||||
#include "roles.hpp"
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
pay, (boost::openmethod::virtual_ptr<const Employee>), double) {
|
||||
return 5000.0;
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Employee)
|
||||
// end::content[]
|
||||
23
doc/modules/ROOT/examples/rolex/1/main.cpp
Normal file
23
doc/modules/ROOT/examples/rolex/1/main.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// tag::content[]
|
||||
// main.cpp
|
||||
|
||||
#include "roles.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
|
||||
Employee bill;
|
||||
Salesman bob; bob.sales = 100'000.0;
|
||||
|
||||
std::cout << "pay bill: $" << pay(bill) << "\n"; // pay bill: $5000
|
||||
std::cout << "pay bob: $" << pay(bob) << "\n"; // pay bob: $10000
|
||||
}
|
||||
// end::content[]
|
||||
23
doc/modules/ROOT/examples/rolex/1/roles.hpp
Normal file
23
doc/modules/ROOT/examples/rolex/1/roles.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// tag::content[]
|
||||
// roles.hpp
|
||||
|
||||
#ifndef ROLES_HPP
|
||||
#define ROLES_HPP
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
struct Employee { virtual ~Employee() = default; };
|
||||
|
||||
struct Salesman : Employee {
|
||||
double sales = 0.0;
|
||||
};
|
||||
|
||||
BOOST_OPENMETHOD(pay, (boost::openmethod::virtual_ptr<const Employee>), double);
|
||||
|
||||
#endif // ROLES_HPP
|
||||
// end::content[]
|
||||
19
doc/modules/ROOT/examples/rolex/1/salesman.cpp
Normal file
19
doc/modules/ROOT/examples/rolex/1/salesman.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// tag::content[]
|
||||
// salesman.cpp
|
||||
|
||||
#include "roles.hpp"
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
pay, (boost::openmethod::virtual_ptr<const Salesman> emp), double) {
|
||||
return next(emp) + emp->sales * 0.05; // base + commission
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Employee, Salesman)
|
||||
|
||||
// end::content[]
|
||||
16
doc/modules/ROOT/examples/rolex/2/employee.cpp
Normal file
16
doc/modules/ROOT/examples/rolex/2/employee.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// tag::content[]
|
||||
#include "roles.hpp"
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
BOOST_OPENMETHOD_DEFINE_OVERRIDER(
|
||||
pay, (boost::openmethod::virtual_ptr<const Employee>), double) {
|
||||
return 5000.0;
|
||||
}
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Employee)
|
||||
// end::content[]
|
||||
23
doc/modules/ROOT/examples/rolex/2/main.cpp
Normal file
23
doc/modules/ROOT/examples/rolex/2/main.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// tag::content[]
|
||||
// main.cpp
|
||||
|
||||
#include "roles.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/openmethod/initialize.hpp>
|
||||
|
||||
int main() {
|
||||
boost::openmethod::initialize();
|
||||
|
||||
Employee bill;
|
||||
Salesman bob; bob.sales = 100'000.0;
|
||||
|
||||
std::cout << "pay bill: $" << pay(bill) << "\n"; // pay bill: $5000
|
||||
std::cout << "pay bob: $" << pay(bob) << "\n"; // pay bob: $10000
|
||||
}
|
||||
// end::content[]
|
||||
26
doc/modules/ROOT/examples/rolex/2/roles.hpp
Normal file
26
doc/modules/ROOT/examples/rolex/2/roles.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// tag::content[]
|
||||
// roles.hpp
|
||||
|
||||
#ifndef ROLES_HPP
|
||||
#define ROLES_HPP
|
||||
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
struct Employee { virtual ~Employee() = default; };
|
||||
|
||||
struct Salesman : Employee {
|
||||
double sales = 0.0;
|
||||
};
|
||||
|
||||
BOOST_OPENMETHOD(pay, (boost::openmethod::virtual_ptr<const Employee>), double);
|
||||
|
||||
BOOST_OPENMETHOD_DECLARE_OVERRIDER(
|
||||
pay, (boost::openmethod::virtual_ptr<const Employee>), double);
|
||||
|
||||
#endif // ROLES_HPP
|
||||
// end::content[]
|
||||
19
doc/modules/ROOT/examples/rolex/2/salesman.cpp
Normal file
19
doc/modules/ROOT/examples/rolex/2/salesman.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "roles.hpp"
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
// tag::content[]
|
||||
BOOST_OPENMETHOD_OVERRIDE(
|
||||
pay, (boost::openmethod::virtual_ptr<const Salesman> emp), double) {
|
||||
return BOOST_OPENMETHOD_OVERRIDER(
|
||||
pay, (boost::openmethod::virtual_ptr<const Employee> emp),
|
||||
double)::fn(emp) +
|
||||
emp->sales * 0.05; // base + commission
|
||||
}
|
||||
// end::content[]
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Employee, Salesman)
|
||||
11
doc/modules/ROOT/examples/rolex/3/employee.cpp
Normal file
11
doc/modules/ROOT/examples/rolex/3/employee.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright (c) 2018-2025 Jean-Louis Leroy
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// tag::content[]
|
||||
#include "roles.hpp"
|
||||
#include <boost/openmethod.hpp>
|
||||
|
||||
BOOST_OPENMETHOD_CLASSES(Employee)
|
||||
// end::content[]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user