Skip to content

Commit

Permalink
headers only, switch to update
Browse files Browse the repository at this point in the history
  • Loading branch information
jll63 committed Jul 29, 2023
1 parent 16c0d95 commit 84ae382
Show file tree
Hide file tree
Showing 65 changed files with 1,725 additions and 1,520 deletions.
12 changes: 6 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ if(${YOMM2_ENABLE_DOC})
add_subdirectory(tutorials)
endif()

set(YOMM2_TRACE "" CACHE STRING "Set trace level (compile time)")
option(YOMM2_ENABLE_TRACE "Enable trace (compile time)" OFF)

if(NOT "${YOMM2_TRACE}" EQUAL "")
message(STATUS "Compiling with YOMM2_TRACE=${YOMM2_ENABLE_TRACE}")
if(NOT "${YOMM2_ENABLE_TRACE}" EQUAL "")
message(STATUS "Compiling with YOMM2_ENABLE_TRACE=${YOMM2_ENABLE_TRACE}")
add_compile_definitions(YOMM2_ENABLE_TRACE=${YOMM2_ENABLE_TRACE})
endif()

Expand All @@ -94,18 +94,18 @@ write_basic_package_version_file(
install(EXPORT YOMM2Targets
FILE YOMM2Targets.cmake
NAMESPACE YOMM2::
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/YOMM2
DESTINATION lib/cmake/YOMM2
)
# Configure package config (tells using code about dependencies)
configure_package_config_file(
cmake/Config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/YOMM2Config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/YOMM2
INSTALL_DESTINATION lib/cmake/YOMM2
)
# Copy config files to install directory
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/YOMM2Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/YOMM2ConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/YOMM2
DESTINATION lib/cmake/YOMM2
)

install(DIRECTORY include/yorel DESTINATION include)
105 changes: 65 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ define_method(std::string, to_json, (const diagonal_matrix& m)) {
}

int main() {
yorel::yomm2::update_methods();
yorel::yomm2::update();

const matrix& a = dense_matrix();
const matrix& b = diagonal_matrix();
Expand All @@ -112,21 +112,35 @@ int main() {
```
The `declare_method` line declares an open method called `to_json`that takes
one virtual argument of type `const matrix&` and returns a std::string. The
`<yorel/yomm2/keywords.hpp>` is the library's main entry point. It declares a
set of macros, and injects a single name, [`virtual_`](virtual_.md), in the global
namespace. The purpose of the header is to make it look as if open methods
are part of the language.
[`register_classes`](use_classes.md) informs the library of the existence of the classes, and
their inheritance relationships. Any class that can appear in a method call
needs to be registered, even if it is not directly referenced by a method.
`declare_method` declares an open method called `to_json`, which takes one
virtual argument of type `const matrix&` and returns a std::string. The
`virtual_<>` decorator specifies that the argument must be taken into account
to select the appropriate specialization. In essence, this is the same thing
as having a `virtual std::string to_json() const` inside class Matrix -
except that the virtual function lives outside of any classes, and you can
add as many as you want without changing the classes.
NOTE: DO NOT specify argument names, i.e. `virtual_<const matrix&> arg` is not
permitted.
add as many as you want without changing the classes. NOTE: DO NOT specify
argument names, i.e. `virtual_<const matrix&> arg` is _not permitted_.
The following `define_method` blocks define two implementations for the
`to_json` method: one for dense matrices, and one for diagonal matrices.
`define_method` defines two implementations for the `to_json` method: one for
dense matrices, and one for diagonal matrices.
`yorel::yomm2::update_methods()` must be called before any method is called,
and after dynamically loading and unloading shared libraries.
`yorel::yomm2::update()` creates the dispatch tables; it must be called
before any method is called, and after dynamically loading and unloading
shared libraries.
The example can be compiled (from the root of the repository) with:
```shell
clang++-14 -I include -std=c++17 tutorials/readme.cpp -o example
```

### Multiple Dispatch

Expand Down Expand Up @@ -197,9 +211,7 @@ cmake ..
make
```
By default, YOMM2 is built as a static library. It can also be built as a shared
library by adding -DYOMM2_SHARED=1 to the `cmake` invocation.
If you want to run the tests:
If you want to run the tests, specify it when running `cmake`:
```
cmake .. -DYOMM2_ENABLE_TESTS=1
Expand All @@ -212,50 +224,62 @@ YOMM2 uses several Boost libraries:
2. Boost.Test: only used to run the test suite
If these libraries are already available on your machine, and they can be found
by `cmake`, they will be used. In this case, make sure that the pre-installed
libraries are at version 1.74 or above. If Boost is not found, the latest
version will be downloaded, and the Boost headers mentioned in section (1) will
be installed along YOMM2 (if you decide to `make install`).
If these libraries are already available on your machine, and they can be
found by `cmake`, they will be used. In this case, make sure that the
pre-installed libraries are at version 1.74 or above. If Boost is not found,
the latest version will be downloaded, and the Boost headers mentioned in
section (1) will be installed along YOMM2 (if you decide to `make install`).
If you also want to run the benchmarks (and in this case you really want a
release build):
```
cmake .. -DYOMM2_ENABLE_TESTS=1 -DYOMM2_ENABLE_BENCHMARKS=1 -DCMAKE_BUILD_TYPE=Release
make && tests/benchmarks # wow it's fast!
make && tests/benchmarks
```
This will automatically download the dependency
[benchmark](https://github.com/google/benchmark), build it and finally install
it to `./extern` within the root directory of yomm2.
Finally, if you like it and you want to install it:
If you like YOMM2, and you want to install it:
```
# either:
sudo make install
# or:
make install DESTDIR=/path/to/my/libs
```
This will install the library and headers, as well as a CMake package
configuration.
Once this is done, link with `libyomm2.a` or `libyomm2.so`. For example:
This will install the headers and a CMake package configuration. By default,
YOMM2 is installed as a headers only library. The examples can be compiled
like this (after installation):
```
clang++ -std=c++17 -O3 examples/synopsis.cpp -o synopsis
```
Or directly from the repository (i.e. without installing):
```
clang++ -std=c++17 synopsis.cpp -o synopsis -lyomm2
clang++ -std=c++17 -O3 -Iinclude examples/synopsis.cpp -o synopsis
```
A CMake package configuration is also installed. If the install location is in
`CMAKE_PREFIX_PATH`, you can use `find_package(YOMM2)` to locate YOMM2, then
`target_link_libraries(<your_target> YOMM2::yomm2)` to add the necessary include
paths and the library. See [this example](examples/cmakeyomm2).
The YOMM2 runtime - responsible for building the dispatch tables - adds ~75K
to the image, or ~64K after stripping.
The runtime can also be built and installed as a shared library, by adding
-DYOMM2_SHARED=1 to the `cmake` command line.
A CMake package configuration is also installed. If the install location is
in `CMAKE_PREFIX_PATH`, you can use `find_package(YOMM2)` to locate YOMM2,
then `target_link_libraries(<your_target> YOMM2::yomm2)` to add the necessary
include paths and the library. See [this example](examples/cmakeyomm2).
Make sure to add the install location to `CMAKE_PREFIX_PATH` so that you can use
`find_package(YOMM2)` from your including project. For linking, the use
`target_link_library(<your_target> YOMM2::yomm2)`. This will automatically add
the necessary include directories, so this should be all you need to do to link
to yomm2.
Make sure to add the install location to `CMAKE_PREFIX_PATH` so that you can
use `find_package(YOMM2)` from your including project. For linking, the use
`target_link_library(<your_target> YOMM2::yomm2)`. This will automatically
add the necessary include directories, so this should be all you need to do
to link to yomm2.
## Going Further
Expand All @@ -279,24 +303,25 @@ The library comes with a series of examples:
* [friendship: an example with namespaces, method containers and friend
declarations](examples/containers)
I presented the library at CppCon 2018. Here are [the video recording](https://www.youtube.com/watch?v=xkxo0lah51s) and [the slides](https://jll63.github.io/yomm2/slides/).
I presented the library at CppCon 2018. Here are [the video
recording](https://www.youtube.com/watch?v=xkxo0lah51s) and [the
slides](https://jll63.github.io/yomm2/slides/).
## Roadmap
YOMM2 has been stable (in the sense of being backward-compatible) for manyyears,
but it is still evolving. Here are the items on which I intend to work in the
future. No promises, no time table!
YOMM2 has been stable (in the sense of being backward-compatible) for many
years, but it is still evolving. Here are the items on which I intend to work
in the future. No promises, no time table.
* Speed up dispatch in presence of virtual inheritance.
* Intrusive mode, &agrave; la YOMM11, for faster dispatch.
* Dispatch on `std::any` and `std::variant`.
* Tunable runtime.
* Static linking of dispatch data.
* *Minimal* perfect hash tables as an option.
* Multi-threaded hash search.
* Make error handler a `std::function`.
* Get closer to Stroustrup et al's papers (version 2.0):
* use covariant return types for disambiguation
* move support for `shared_ptr` and `unique_ptr` to an optional header
* Go header-only.
If you have ideas, comments, suggestions...get in touch! If you use YOMM2, I
would appreciate it if you take the time to send me a description of your use
Expand Down
4 changes: 2 additions & 2 deletions docs/cppnow2018/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ namespace { struct Init {
Init init;
} }

#include <yorel/yomm2/cute.hpp>
#include <yorel/yomm2/keywords.hpp>

using yorel::yomm2::virtual_;

Expand Down Expand Up @@ -197,7 +197,7 @@ int main() {
cout << visitor::toRPN(*expr) << " = " << expr->value() << "\n";
cout << funtable::toRPN(*expr) << " = " << expr->value() << "\n";

yorel::yomm2::update_methods();
yorel::yomm2::update();
cout << openmethods::toRPN(*expr) << " = " << expr->value() << "\n";


Expand Down
4 changes: 2 additions & 2 deletions docs/slides/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ namespace { struct Init {
Init init;
} }

#include <yorel/yomm2/cute.hpp>
#include <yorel/yomm2/keywords.hpp>

using yorel::yomm2::virtual_;

Expand Down Expand Up @@ -197,7 +197,7 @@ int main() {
cout << visitor::toRPN(*expr) << " = " << expr->value() << "\n";
cout << funtable::toRPN(*expr) << " = " << expr->value() << "\n";

yorel::yomm2::update_methods();
yorel::yomm2::update();
cout << openmethods::toRPN(*expr) << " = " << expr->value() << "\n";


Expand Down
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ if(NOT MSVC AND NOT XCODE_VERSION)
set_target_properties(dl_main PROPERTIES LINK_FLAGS "-Wl,-export-dynamic")
endif()
target_link_libraries(dl_main YOMM2::yomm2 dl)
target_link_libraries(dl_shared YOMM2::yomm2)
endif()
2 changes: 1 addition & 1 deletion examples/accept_no_visitors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ define_method(string, as_lisp, (const Integer& expr)) {
// -----------------------------------------------------------------------------

int main() {
yorel::yomm2::update_methods();
yorel::yomm2::update();

shared_ptr<Node> expr = make_shared<Times>(
make_shared<Integer>(2),
Expand Down
2 changes: 1 addition & 1 deletion examples/adventure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ define_method(std::string, fight, (Character & x, Dragon& y, Hands& z)) {
}

int main() {
yorel::yomm2::update_methods();
yorel::yomm2::update();

std::unique_ptr<Character> bob = std::make_unique<Character>(),
rambo = std::make_unique<Warrior>();
Expand Down
2 changes: 1 addition & 1 deletion examples/asteroids.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ define_method(void, collideWith, (Spaceship& left, Spaceship& right)) {
}

int main() {
yorel::yomm2::update_methods();
yorel::yomm2::update();

Asteroid a1, a2;
Spaceship s1, s2;
Expand Down
4 changes: 2 additions & 2 deletions examples/containers/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// This exmaple is based on sample code provided by Github user matpen in
// https://github.com/jll63/yomm2/issues/7

#include <yorel/yomm2/cute.hpp>
#include <yorel/yomm2/keywords.hpp>

#include <iostream>

Expand All @@ -17,7 +17,7 @@ using yorel::yomm2::virtual_;
using std::cout;

int main() {
yorel::yomm2::update_methods();
yorel::yomm2::update();

const geometries::Geometry& arc = geometries::Arc();
const geometries::Geometry& segment = geometries::Segment();
Expand Down
6 changes: 3 additions & 3 deletions examples/dl_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ define_method(string, encounter, (const Animal&, const Animal&)) {
}

int main() {
yorel::yomm2::update_methods();
yorel::yomm2::update();

cout << "Before loading library\n";
cout << "encounter(Cow(), Wolf()) -> " << encounter(Cow(), Wolf()) << endl;
Expand All @@ -44,7 +44,7 @@ int main() {
}

cout << "\nAfter loading library\n";
yorel::yomm2::update_methods();
yorel::yomm2::update();

using make_tyget_type = Animal* (*)();
make_tyget_type make_tiger =
Expand All @@ -62,7 +62,7 @@ int main() {
dlclose(handle);

cout << "\nAfter unloading library\n";
yorel::yomm2::update_methods();
yorel::yomm2::update();

cout << "encounter(Cow(), Wolf()) -> " << encounter(Cow(), Wolf()) << endl;
cout << "encounter(Wolf(), Cow()) -> " << encounter(Wolf(), Cow()) << endl;
Expand Down
2 changes: 1 addition & 1 deletion examples/matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ int main() {
using std::cout;
using std::cerr;

yorel::yomm2::update_methods();
yorel::yomm2::update();

shared_ptr<const matrix> a = make_shared<dense_matrix>();
shared_ptr<const matrix> b = make_shared<diagonal_matrix>();
Expand Down
2 changes: 1 addition & 1 deletion examples/next.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ define_method(void, inspect, (const Car& v, const StateInspector& i)) {
}

int main() {
yorel::yomm2::update_methods();
yorel::yomm2::update();

const Vehicle& vehicle1 = Car();
const Inspector& inspector1 = StateInspector();
Expand Down
4 changes: 2 additions & 2 deletions examples/synopsis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ define_method(void, meet, (Cat& cat, Dog& dog, std::ostream& os)) {

int main() {
// Initialise method dispatch tables.
yorel::yomm2::update_methods();
yorel::yomm2::update();

// Create a few objects.
// Note that the actual classes are type-erased to base class Animal!
Expand Down Expand Up @@ -169,7 +169,7 @@ void call_meet(Animal& a, Animal& b, std::ostream& os) {
// shr r9, cl ; index of method table for 'b'

// mov rcx, qword ptr [rip + method+96] ; offset of 'meet' in method table for 'a'

// mov r10, qword ptr [rax + 8*rcx] ; pointer to row for 'a' in dispatch table
// mov rcx, qword ptr [r8 + 8*r9] ; method table for 'b'
// mov rax, qword ptr [rip + method+104] ; offset of 'meet' in method table for 'b'
Expand Down
Loading

0 comments on commit 84ae382

Please sign in to comment.