diff --git a/CMakeLists.txt b/CMakeLists.txt index 121b895..7cc1363 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,5 +49,5 @@ endif() if(BUILD_EXAMPLES) message(STATUS "Building examples") - add_subdirectory(examples) + add_subdirectory(example) endif() diff --git a/doc/BOOST_OPENMETHOD_DEFAULT_POLICY.adoc b/doc/BOOST_OPENMETHOD_DEFAULT_REGISTRY.adoc similarity index 100% rename from doc/BOOST_OPENMETHOD_DEFAULT_POLICY.adoc rename to doc/BOOST_OPENMETHOD_DEFAULT_REGISTRY.adoc diff --git a/doc/basic_policy.adoc b/doc/basic_policy.adoc index 1d39301..374f58a 100644 --- a/doc/basic_policy.adoc +++ b/doc/basic_policy.adoc @@ -131,7 +131,7 @@ struct release; ``` A policy that contains facets `std_rtti`, `fast_perfect_hash`, `vptr_vector` and -`vectored_error_handler`. +`default_error_handler`. #### debug diff --git a/doc/core_api.adoc b/doc/core_api.adoc index fb2eeee..7d44ff1 100644 --- a/doc/core_api.adoc +++ b/doc/core_api.adoc @@ -29,7 +29,7 @@ name can get tedious, so OpenMethod provides a macro for that: [source,c++] ---- -include::{examplesdir}/core_api.cpp[tag=method] +include::{exampledir}/core_api.cpp[tag=method] ---- NOTE: BOOST_OPENMETHOD and associated macros use `BOOST_OPENMETHOD_NAME` in @@ -48,7 +48,7 @@ Overriders are ordinary functions, added to a method using the nested template [source,c++] ---- -include::{examplesdir}/core_api.cpp[tag=poke_cat] +include::{exampledir}/core_api.cpp[tag=poke_cat] ---- NOTE: `override` can register multiple overriders. @@ -58,14 +58,14 @@ identifier. In the meantime, OpenMethod provides a small convenience macro: [source,c++] ---- -include::{examplesdir}/core_api.cpp[tag=poke_dog] +include::{exampledir}/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] +include::{exampledir}/core_api.cpp[tag=poke_bulldog] ---- NOTE: Since the function uses itself as a template argument in its body, its @@ -81,12 +81,12 @@ We register the classes with `use_classes`: [source,c++] ---- -include::{examplesdir}/core_api.cpp[tag=use_classes] +include::{exampledir}/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] +include::{exampledir}/core_api.cpp[tag=main] ---- diff --git a/doc/custom_rtti.adoc b/doc/custom_rtti.adoc index 04ff726..8775810 100644 --- a/doc/custom_rtti.adoc +++ b/doc/custom_rtti.adoc @@ -101,7 +101,7 @@ Here is the facet implementation: [source,c++] ---- -include::{examplesdir}/custom_rtti.cpp[tag=facet] +include::{exampledir}/custom_rtti.cpp[tag=facet] ---- This facet is quite minimal. It does not support virtual inheritance. It would @@ -113,7 +113,7 @@ CRTP template: [source,c++] ---- -include::{examplesdir}/custom_rtti.cpp[tag=policy] +include::{exampledir}/custom_rtti.cpp[tag=policy] ---- Next, we include the main header. Because `BOOST_OPENMETHOD_DEFAULT_REGISTRY` is @@ -121,7 +121,7 @@ defined, its value is used for the default policy. Then comes the usual example. [source,c++] ---- -include::{examplesdir}/custom_rtti.cpp[tag=example] +include::{exampledir}/custom_rtti.cpp[tag=example] ---- This programs works even if standard RTTI is disabled. @@ -141,7 +141,7 @@ This time let's support virtual inheritance as well. First the domain classes: [source,c++] ---- -include::{examplesdir}/deferred_custom_rtti.cpp[tag=classes] +include::{exampledir}/deferred_custom_rtti.cpp[tag=classes] // ditto for Dog ---- @@ -152,7 +152,7 @@ The rtti facet is the same, with one more function: struct custom_rtti : bom::policies::rtti { // as before -include::{examplesdir}/deferred_custom_rtti.cpp[tag=dynamic_cast_ref] +include::{exampledir}/deferred_custom_rtti.cpp[tag=dynamic_cast_ref] }; ---- diff --git a/doc/vectored_error_handler.adoc b/doc/default_error_handler.adoc similarity index 82% rename from doc/vectored_error_handler.adoc rename to doc/default_error_handler.adoc index 507b910..71fcae7 100644 --- a/doc/vectored_error_handler.adoc +++ b/doc/default_error_handler.adoc @@ -1,15 +1,15 @@ -## vectored_error_handler +## default_error_handler ### Synopsis -Defined in . +Defined in . ```c++ namespace boost::openmethod::policies { template -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 diff --git a/doc/dynamic_loading.adoc b/doc/dynamic_loading.adoc index 0955101..47c843d 100644 --- a/doc/dynamic_loading.adoc +++ b/doc/dynamic_loading.adoc @@ -21,7 +21,7 @@ Here is an example: [source,c++] ---- -include::{examplesdir}/dl.hpp[tag=header] +include::{exampledir}/dl.hpp[tag=header] ---- NOTE: The policy must be passed to the method as well as the @@ -35,7 +35,7 @@ We can now register the classes and and provide an overrider: [source,c++] ---- -include::{examplesdir}/dl_main.cpp[tag=main] +include::{exampledir}/dl_main.cpp[tag=main] ---- At this point we only have one overrider. Animals of all species ignore one @@ -43,26 +43,26 @@ another: [source,c++] ---- -include::{examplesdir}/dl_main.cpp[tag=before_dlopen] +include::{exampledir}/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] +include::{exampledir}/dl_shared.cpp[tag=dl_shared] ---- Now back to `main`: [source,c++] ---- -include::{examplesdir}/dl_main.cpp[tag=dlopen] +include::{exampledir}/dl_main.cpp[tag=dlopen] ---- After unloading the library, we must call `initialize` again: [source,c++] ---- -include::{examplesdir}/dl_main.cpp[tag=after_dlclose] +include::{exampledir}/dl_main.cpp[tag=after_dlclose] ---- diff --git a/doc/error_handling.adoc b/doc/error_handling.adoc index 9f1acf0..3337d6a 100644 --- a/doc/error_handling.adoc +++ b/doc/error_handling.adoc @@ -5,14 +5,14 @@ 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 +`default_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] +include::{exampledir}/default_error_handler.cpp[tag=example] ---- Output: @@ -29,7 +29,7 @@ We can also replace the `error_handler` facet with our own. For example: [source,c++] ---- -include::{examplesdir}/throw_error_handler.cpp[tag=example] +include::{exampledir}/throw_error_handler.cpp[tag=example] ---- [source,console] diff --git a/doc/friendship.adoc b/doc/friendship.adoc index ce7d91d..1590db2 100644 --- a/doc/friendship.adoc +++ b/doc/friendship.adoc @@ -17,7 +17,7 @@ We can thus grant friendship to all the overriders of `poke`: [source,c++] ---- -include::{examplesdir}/friendship.cpp[tag=friend_all] +include::{exampledir}/friendship.cpp[tag=friend_all] ---- Be aware, though, that the overriders of _any_ method called `poke` - with any @@ -27,5 +27,5 @@ We can also befriend individual overriders: [source,c++] ---- -include::{examplesdir}/friendship.cpp[tag=friend] +include::{exampledir}/friendship.cpp[tag=friend] ---- diff --git a/doc/headers_namespaces.adoc b/doc/headers_namespaces.adoc index f6cb59b..536d28e 100644 --- a/doc/headers_namespaces.adoc +++ b/doc/headers_namespaces.adoc @@ -11,7 +11,7 @@ Let's break the Animals example into headers and namespaces. First we put [source,c++] ---- -include::{examplesdir}/headers_namespaces/animal.hpp[] +include::{exampledir}/headers_namespaces/animal.hpp[] ---- `BOOST_OPENMETHOD` can be placed in a header file. It adds several constructs to @@ -32,12 +32,12 @@ Next, let's implement the `Cat` class, and a derived class, `Cheetah`, in the [source,c++] ---- -include::{examplesdir}/headers_namespaces/cat.hpp[] +include::{exampledir}/headers_namespaces/cat.hpp[] ---- [source,c++] ---- -include::{examplesdir}/headers_namespaces/cat.cpp[] +include::{exampledir}/headers_namespaces/cat.cpp[] ---- `BOOST_OPENMETHOD_CLASSES` should be placed in an implementation file. It can @@ -83,7 +83,7 @@ the static function `fn` just yet. [source,c++] ---- -include::{examplesdir}/headers_namespaces/dog.hpp[] +include::{exampledir}/headers_namespaces/dog.hpp[] ---- Unlike function declarations, which can occur multiple times in a TU, an @@ -101,7 +101,7 @@ Now we use `BOOST_OPENMETHOD_DEFINE_OVERRIDER` to define the overrider: [source,c++] ---- -include::{examplesdir}/headers_namespaces/dog.cpp[] +include::{exampledir}/headers_namespaces/dog.cpp[] ---- Let's look at the main program now. It derived `Bulldog` from `Dog` and provides @@ -109,7 +109,7 @@ an overrider for the new class: [source,c++] ---- -include::{examplesdir}/headers_namespaces/main.cpp[] +include::{exampledir}/headers_namespaces/main.cpp[] ---- Again ADL plays a role: it helps the overrider (and `main`) to locate the `poke` diff --git a/doc/hello_world.adoc b/doc/hello_world.adoc index b78b17f..52e0755 100644 --- a/doc/hello_world.adoc +++ b/doc/hello_world.adoc @@ -6,7 +6,7 @@ functions: [source,c++] ---- -include::{examplesdir}/virtual_func.cpp[tag=code] +include::{exampledir}/virtual_func.cpp[tag=code] ---- We are going to rewrite this using open-methods. @@ -15,7 +15,7 @@ First we remove the `poke` virtual functions from the domain classes: [source,c++] ---- -include::{examplesdir}/hello_world.cpp[tag=domain_classes] +include::{exampledir}/hello_world.cpp[tag=domain_classes] ---- Note that the Animal classes do not depend on iostreams anymore. This is a major @@ -28,7 +28,7 @@ namespace. [source,c++] ---- -include::{examplesdir}/hello_world.cpp[tag=method] +include::{exampledir}/hello_world.cpp[tag=method] ---- This defines a free function called `poke`, which takes two arguments. The first @@ -45,7 +45,7 @@ Let's add overriders for `Cat` and `Dog`: [source,c++] ---- -include::{examplesdir}/hello_world.cpp[tag=overriders] +include::{exampledir}/hello_world.cpp[tag=overriders] ---- `Bulldog::poke` calls the `poke` it overrides in its `Dog` base. The equivalent @@ -55,7 +55,7 @@ been called if the overrider did not exist. [source,c++] ---- -include::{examplesdir}/hello_world.cpp[tag=next] +include::{exampledir}/hello_world.cpp[tag=next] ---- All classes involved in open-method calls need to be registered using the @@ -63,7 +63,7 @@ All classes involved in open-method calls need to be registered using the [source,c++] ---- -include::{examplesdir}/hello_world.cpp[tag=classes] +include::{exampledir}/hello_world.cpp[tag=classes] ---- Classes can be registered incrementally, as long as all the direct bases of a @@ -85,7 +85,7 @@ It builds the dispatch tables. Typically this is done in `main`: [source,c++] ---- -include::{examplesdir}/hello_world.cpp[tag=main,indent=0] +include::{exampledir}/hello_world.cpp[tag=main,indent=0] ---- We call `poke` like any ordinary function. We can pass it the animals by @@ -94,5 +94,5 @@ reference, because `virtual_ptr` has a conversion constructor for that: [source,c++] ---- -include::{examplesdir}/hello_world.cpp[tag=call] +include::{exampledir}/hello_world.cpp[tag=call] ---- diff --git a/doc/html/index.html b/doc/html/index.html index a0bb1ec..c7a1539 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -719,7 +719,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
  • Requirements
  • -
  • vectored_error_handler +
  • default_error_handler
    • Synopsis
    • Description
    • @@ -733,37 +733,23 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
    • Members
  • -
  • output +
  • basic_error_output -
  • -
  • basic_error_output -
  • -
  • trace - -
  • basic_trace_output
  • RestrictedOutputStream
  • @@ -984,6 +970,8 @@ namespace.

    #include <iostream>
     #include <boost/openmethod.hpp>
     
    +using boost::openmethod::virtual_ptr;
    +
     BOOST_OPENMETHOD(
         poke,                                       // method name
         (std::ostream&, virtual_ptr<Animal>),       // method signature
    @@ -1115,7 +1103,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";
     }
     
    @@ -1191,7 +1179,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
     
    @@ -1220,7 +1209,7 @@ method (with the virtual_ decorators stripped).

    -

    Next, let’s implement the Cat class, and a derived class, Chhetah, in the +

    Next, let’s implement the Cat class, and a derived class, Cheetah, in the felines namespace:

    @@ -1256,6 +1245,8 @@ struct Cheetah : Cat { #include "cat.hpp" +using boost::openmethod::virtual_ptr; + namespace felines { BOOST_OPENMETHOD_CLASSES(animals::Animal, Cat, Cheetah); @@ -1355,7 +1346,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 @@ -1390,7 +1381,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"; } @@ -1411,6 +1402,8 @@ an overrider for the new class:

    #include "cat.hpp" #include "dog.hpp" +using boost::openmethod::virtual_ptr; + struct Bulldog : canines::Dog { using Dog::Dog; }; @@ -1482,7 +1475,7 @@ BOOST_OPENMETHOD_OVERRIDE(

    …​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 canines and felides namespaces, with the same name.

    +containers exist in both the canines and felines namespaces, with the same name.

    Finally, the names passed as first arguments to the BOOST_OPENMETHOD and @@ -1662,6 +1655,8 @@ stored in variables in place of plain pointers.

    #include <boost/openmethod.hpp> #include <boost/openmethod/compiler.hpp> +using boost::openmethod::virtual_ptr; + struct Node { virtual ~Node() {} }; @@ -1799,8 +1794,7 @@ pointers:

    #include <boost/openmethod/unique_ptr.hpp> #include <boost/openmethod/compiler.hpp> -using boost::openmethod::unique_virtual_ptr; -using boost::openmethod::make_unique_virtual; +using namespace boost::openmethod::aliases; struct Node { virtual ~Node() {} @@ -1878,7 +1872,7 @@ using boost::openmethod::virtual_; BOOST_OPENMETHOD(poke, (std::ostream&, virtual_<Animal&>), void); -BOOST_OPENMETHOD_OVERRIDE(poke, (std::ostream & os, Cat& cat), void) { +BOOST_OPENMETHOD_OVERRIDE(poke, (std::ostream & os, Cat& /*cat*/), void) { os << "hiss"; } @@ -1919,7 +1913,7 @@ native virtual functions:

    class Animal {
       protected:
         boost::openmethod::vptr_type vptr;
    -    friend auto boost_openmethod_vptr(const Animal& a) {
    +    friend auto boost_openmethod_vptr(const Animal& a, void*) {
             return a.vptr;
         }
     
    @@ -1938,7 +1932,7 @@ class Cat : public Animal {
     
     BOOST_OPENMETHOD(poke, (std::ostream&, virtual_<Animal&>), void);
     
    -BOOST_OPENMETHOD_OVERRIDE(poke, (std::ostream & os, Cat& cat), void) {
    +BOOST_OPENMETHOD_OVERRIDE(poke, (std::ostream & os, Cat& /*cat*/), void) {
         os << "hiss\n";
     }
     
    @@ -1982,7 +1976,7 @@ class Cat : public Animal, public boost::openmethod::with_vptr<Cat, Animal>
     
     BOOST_OPENMETHOD(poke, (std::ostream&, virtual_<Animal&>), void);
     
    -BOOST_OPENMETHOD_OVERRIDE(poke, (std::ostream & os, Cat& cat), void) {
    +BOOST_OPENMETHOD_OVERRIDE(poke, (std::ostream & os, Cat& /*cat*/), void) {
         os << "hiss\n";
     }
     
    @@ -2039,7 +2033,8 @@ name can get tedious, so OpenMethod provides a macro for that:

    class BOOST_OPENMETHOD_NAME(poke); using poke = method< - BOOST_OPENMETHOD_NAME(poke)(std::ostream&, virtual_ptr<Animal>), void>;
    + BOOST_OPENMETHOD_NAME(poke), + auto(std::ostream&, virtual_ptr<Animal>)->void>;
    @@ -2070,7 +2065,7 @@ styles.
    -
    auto poke_cat(std::ostream& os, virtual_ptr<Cat> cat) {
    +
    auto poke_cat(std::ostream& os, virtual_ptr<Cat> /*cat*/) {
         os << "hiss";
     }
     
    @@ -2097,7 +2092,7 @@ identifier. In the meantime, OpenMethod provides a small convenience macro:

    #include <boost/openmethod/macros.hpp>
     
    -auto poke_dog(std::ostream& os, virtual_ptr<Dog> dog) {
    +auto poke_dog(std::ostream& os, virtual_ptr<Dog> /*dog*/) {
         os << "bark";
     }
     
    @@ -2226,7 +2221,7 @@ library: release and debug.

    error_handler

    -

    vectored_error_handler

    +

    default_error_handler

    handles errors

    @@ -2303,7 +2298,7 @@ has no effect.

    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 +default_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:

    @@ -2316,6 +2311,8 @@ handler can be set with set_error_handler:

    #include <boost/openmethod.hpp> #include <boost/openmethod/compiler.hpp> +using boost::openmethod::virtual_ptr; + struct Animal { virtual ~Animal() = default; }; @@ -2328,7 +2325,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"; } @@ -2336,12 +2333,11 @@ auto main() -> int { namespace bom = boost::openmethod; bom::initialize(); - bom::default_registry::set_error_handler( - [](const bom::default_registry::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::not_implemented_error>(error)) { + throw std::runtime_error("not implemented"); + } + }); Cat felix; Dog hector, snoopy; @@ -2376,7 +2372,7 @@ spin
    #include <iostream>
     
    -#include <boost/openmethod/policies.hpp>
    +#include <boost/openmethod/default_registry.hpp>
     
     struct Animal {
         virtual ~Animal() = default;
    @@ -2388,28 +2384,33 @@ struct Dog : Animal {};
     namespace bom = boost::openmethod;
     
     struct throw_if_not_implemented : bom::policies::error_handler {
    -    static auto error(const bom::openmethod_error&) -> void {
    -    }
    +    template<class Registry>
    +    struct fn {
    +        static auto error(const bom::openmethod_error&) -> void {
    +        }
     
    -    static auto error(const bom::not_implemented_error& err) -> void {
    -        throw err;
    -    }
    +        static auto error(const bom::not_implemented_error& err) -> void {
    +            throw err;
    +        }
    +    };
     };
     
    -struct throwing_policy : bom::default_registry::fork<throwing_policy>::with<
    -                             throw_if_not_implemented> {};
    +struct custom_registry : bom::default_registry::with<throw_if_not_implemented> {
    +};
     
    -#define BOOST_OPENMETHOD_DEFAULT_REGISTRY throwing_policy
    +#define BOOST_OPENMETHOD_DEFAULT_REGISTRY custom_registry
     
     #include <boost/openmethod.hpp>
     #include <boost/openmethod/compiler.hpp>
     
    +using boost::openmethod::virtual_ptr;
    +
     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";
     }
     
    @@ -2423,7 +2424,7 @@ auto main() -> int {
         for (auto animal : animals) {
             try {
                 trick(std::cout, *animal);
    -        } catch (bom::not_implemented_error) {
    +        } catch (bom::not_implemented_error&) {
                 std::cout << "not implemented\n";
             }
         }
    @@ -2577,26 +2578,29 @@ define the custom RTTI facet. We must not include
     
    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::fn<Registry> {
    +        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;
    +            }
             }
    -    }
    +    };
     };
    @@ -2611,9 +2615,8 @@ CRTP template:

    -
    struct custom_policy : bom::policies::basic_policy<
    -                           custom_policy, custom_rtti,
    -                           bom::policies::vptr_vector<custom_policy>> {};
    +
    struct custom_policy : bom::registry<custom_rtti, bom::policies::vptr_vector> {
    +};
     
     #define BOOST_OPENMETHOD_DEFAULT_REGISTRY custom_policy
    @@ -2629,15 +2632,17 @@ defined, its value is used for the default policy. Then comes the usual example. #include <boost/openmethod.hpp> #include <boost/openmethod/compiler.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"; } @@ -2742,16 +2747,16 @@ custom_type_info Cat::type_info;
    struct custom_rtti : bom::policies::rtti {
         // as before
     
    -    // 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
    +        // 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
    +            }
             }
    -    }
     };
    @@ -2823,9 +2828,8 @@ struct Carnivore : Animal {}; struct Cow : Herbivore {}; struct Wolf : Carnivore {}; -struct dynamic_policy - : boost::openmethod::default_registry::fork<dynamic_policy>::with< - boost::openmethod::policies::indirect_vptr> {}; +struct dynamic_policy : boost::openmethod::default_registry::with< + boost::openmethod::policies::indirect_vptr> {}; template<class Class> using dyn_vptr = boost::openmethod::virtual_ptr<Class, dynamic_policy>; @@ -3185,7 +3189,7 @@ etc).

    -
    <boost/openmethod/policies/vectored_error_handler.hpp>
    +
    <boost/openmethod/policies/default_error_handler.hpp>

    Implements the error_handler facet by routing the error through a std::function.

    @@ -5156,7 +5160,7 @@ will not be used.

    A policy that contains facets std_rtti, fast_perfect_hash, vptr_vector and -vectored_error_handler.

    +default_error_handler.

    @@ -5968,18 +5972,18 @@ termination by throwing an exception.

    -

    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>.

    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,
    @@ -5999,7 +6003,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.

    @@ -6076,47 +6080,9 @@ throws the error as an exception.

    -

    output

    -
    -

    Synopsis

    -
    -

    Defined in <boost/openmethod/policies/basic_policy.hpp>.

    -
    -
    -
    -
    namespace boost::openmethod::policies {
    -
    -struct output : facet {};
    -
    -} // boost::openmethod::policies
    -
    -
    -
    -
    -

    Description

    -
    -

    output is a facet that provides a stream for writing error messages.

    -
    -
    -
    -

    Requirements

    -
    -
    error_stream
    -
    -
    -
    static RestrictedOutputStream error_stream;
    -
    -
    -
    -

    A static variable that satisfies the requirements of RestrictedOutputStream.

    -
    -
    -
    -
    -

    basic_error_output

    -

    Synopsis

    +

    Synopsis

    Defined in <boost/openmethod/policies/basic_error_output.hpp>.

    @@ -6134,7 +6100,7 @@ struct basic_error_output : output {
    -

    Description

    +

    Description

    basic_error_output is an implementation of output that writes error messages to a RestrictedOutputStream.

    @@ -6143,7 +6109,7 @@ messages to a RestrictedOutputStream.

    Members

    -
    error_stream
    +
    error_stream
    Stream  error_stream;
    @@ -6158,67 +6124,9 @@ it.

    -

    trace

    -
    -

    Synopsis

    -
    -

    Defined in <boost/openmethod/policies/basic_policy.hpp>.

    -
    -
    -
    -
    namespace boost::openmethod::policies {
    -
    -struct trace : facet {};
    -
    -}
    -
    -
    -
    -
    -
    -

    Description

    -
    -

    trace is a facet used to write trace messages.

    -
    -
    -

    initialize can be directed to describe the classes and methods in a policy, -and how the dispatch tables are built, by including this facet in the policy, -and setting trace_enabled to true. The content and the format of the -description is not documented, beyond the guarantee that it provides an -exhaustive account of table construction, and may change between major, minor -and patch versions.

    -
    -
    -
    -

    Requirements

    -
    -
    trace_enabled
    -
    -
    -
    static bool trace_enabled;
    -
    -
    -
    -

    true if tracing is enabled, false otherwise.

    -
    -
    -
    -
    trace_stream
    -
    -
    -
    static RestrictedOutputStream trace_stream;
    -
    -
    -
    -

    A static variable that satisfies the requirements of RestrictedOutputStream.

    -
    -
    -
    -
    -

    basic_trace_output

    -

    Synopsis

    +

    Synopsis

    Defined in <boost/openmethod/policies/basic_trace_output.hpp>.

    @@ -6237,7 +6145,7 @@ struct basic_trace_output : trace {
    -

    Description

    +

    Description

    basic_error_output is an implementation of trace that writes error messages to a RestrictedOutputStream.

    @@ -6246,7 +6154,7 @@ messages to a RestrictedOutputStream.

    Members

    -
    trace_enabled
    +
    trace_enabled
    static bool trace_enabled;
    @@ -6257,7 +6165,7 @@ messages to a RestrictedOutputStream.

    -
    trace_stream
    +
    trace_stream
    static Stream trace_stream;
    @@ -6274,7 +6182,7 @@ open it.

    RestrictedOutputStream

    -

    Description

    +

    Description

    RestrictedOutputStream is a concept describing a std::ostream-like class with a reduced set of operations.

    @@ -6345,4 +6253,4 @@ Last updated 2025-03-08 15:24:21 -0500
    - + \ No newline at end of file diff --git a/doc/multiple_dispatch.adoc b/doc/multiple_dispatch.adoc index f9e434d..dcdd7e5 100644 --- a/doc/multiple_dispatch.adoc +++ b/doc/multiple_dispatch.adoc @@ -5,12 +5,12 @@ A method can have more than one `virtual_ptr` parameter. For example: [source,c++] ---- -include::{examplesdir}/hello_world.cpp[tag=multi] +include::{exampledir}/hello_world.cpp[tag=multi] ---- [source,c++] ---- -include::{examplesdir}/hello_world.cpp[tag=multi_call,indent=0] +include::{exampledir}/hello_world.cpp[tag=multi_call,indent=0] ---- The appropriate overrider is selected using a process similar to overload diff --git a/doc/basic_error_output.adoc b/doc/output.adoc similarity index 100% rename from doc/basic_error_output.adoc rename to doc/output.adoc diff --git a/doc/overview.adoc b/doc/overview.adoc index 3fc4236..17a285c 100644 --- a/doc/overview.adoc +++ b/doc/overview.adoc @@ -124,7 +124,7 @@ Implements the `extern_vptr` facet using a map of pointers. Implements the `type_hash` facet using a perfect hash function. -#### +#### Implements the `error_handler` facet by routing the error through a `std::function`. diff --git a/doc/performance.adoc b/doc/performance.adoc index 62689fa..325a94c 100644 --- a/doc/performance.adoc +++ b/doc/performance.adoc @@ -8,7 +8,7 @@ clang compiles the following code: [source,c++] ---- -include::{examplesdir}/hello_world.cpp[tag=call_poke_via_ref] +include::{exampledir}/hello_world.cpp[tag=call_poke_via_ref] ---- ...to this on the x64 architecture (variable names have been shortened for @@ -48,7 +48,7 @@ Let's look at another example: an AST for an arithmetic calculator: [source,c++] ---- -include::{examplesdir}/ast.cpp[tag=ast] +include::{exampledir}/ast.cpp[tag=ast] ---- The `Negate` overrider compiles to: @@ -79,7 +79,7 @@ instruction. For example: [source,c++] ---- -include::{examplesdir}/ast.cpp[tag=final,indent=0] +include::{exampledir}/ast.cpp[tag=final,indent=0] ---- ...compiles to: diff --git a/doc/policies.adoc b/doc/policies.adoc index b5c5859..87ccd69 100644 --- a/doc/policies.adoc +++ b/doc/policies.adoc @@ -38,7 +38,7 @@ The `release` policy contains the following facets: | hash type id to an index in a vector | error_handler -| vectored_error_handler +| default_error_handler | handles errors |=== diff --git a/doc/reference.adoc b/doc/reference.adoc index 8e96b62..3386617 100644 --- a/doc/reference.adoc +++ b/doc/reference.adoc @@ -41,10 +41,8 @@ include::vptr_vector.adoc[] include::vptr_map.adoc[] include::type_hash.adoc[] include::error_handler.adoc[] -include::vectored_error_handler.adoc[] +include::default_error_handler.adoc[] include::throw_error_handler.adoc[] include::output.adoc[] -include::basic_error_output.adoc[] include::trace.adoc[] -include::basic_trace_output.adoc[] include::restricted_output_stream.adoc[] diff --git a/doc/smart_pointers.adoc b/doc/smart_pointers.adoc index f56df9d..d471ce2 100644 --- a/doc/smart_pointers.adoc +++ b/doc/smart_pointers.adoc @@ -17,5 +17,5 @@ pointers: [source,c++] ---- -include::{examplesdir}/ast_unique_ptr.cpp[tag=ast,indent=0] +include::{exampledir}/ast_unique_ptr.cpp[tag=ast,indent=0] ---- diff --git a/doc/basic_trace_output.adoc b/doc/trace.adoc similarity index 100% rename from doc/basic_trace_output.adoc rename to doc/trace.adoc diff --git a/doc/tutorial.adoc b/doc/tutorial.adoc index 3be5cd6..be51210 100644 --- a/doc/tutorial.adoc +++ b/doc/tutorial.adoc @@ -4,7 +4,7 @@ :toc: :toc-title: :idprefix: tutorials_ -:examplesdir: ../examples +:exampledir: ../example include::hello_world.adoc[] include::multiple_dispatch.adoc[] diff --git a/doc/virtual_ptr_alt.adoc b/doc/virtual_ptr_alt.adoc index 3c1911d..51f53cd 100644 --- a/doc/virtual_ptr_alt.adoc +++ b/doc/virtual_ptr_alt.adoc @@ -9,7 +9,7 @@ For example, the `poke` open-method in the Animals example can be rewritten as: [source,c++] ---- -include::{examplesdir}/virtual_.cpp[tag=virtual_parameter,indent=0] +include::{exampledir}/virtual_.cpp[tag=virtual_parameter,indent=0] int main() { boost::openmethod::initialize(); @@ -39,7 +39,7 @@ native virtual functions: [source,c++] ---- -include::{examplesdir}/virtual_.cpp[tag=virtual_intrusive,indent=0] +include::{exampledir}/virtual_.cpp[tag=virtual_intrusive,indent=0] int main() { boost::openmethod::initialize(); @@ -58,7 +58,7 @@ vptrs. [source,c++] ---- -include::{examplesdir}/virtual_.cpp[tag=with_vptr,indent=0] +include::{exampledir}/virtual_.cpp[tag=with_vptr,indent=0] int main() { boost::openmethod::initialize(); diff --git a/examples/CMakeLists.txt b/example/CMakeLists.txt similarity index 100% rename from examples/CMakeLists.txt rename to example/CMakeLists.txt diff --git a/examples/accept_no_visitors.cpp b/example/accept_no_visitors.cpp similarity index 100% rename from examples/accept_no_visitors.cpp rename to example/accept_no_visitors.cpp diff --git a/examples/adventure.cpp b/example/adventure.cpp similarity index 100% rename from examples/adventure.cpp rename to example/adventure.cpp diff --git a/examples/ast.cpp b/example/ast.cpp similarity index 100% rename from examples/ast.cpp rename to example/ast.cpp diff --git a/examples/ast_unique_ptr.cpp b/example/ast_unique_ptr.cpp similarity index 100% rename from examples/ast_unique_ptr.cpp rename to example/ast_unique_ptr.cpp diff --git a/examples/asteroids.cpp b/example/asteroids.cpp similarity index 100% rename from examples/asteroids.cpp rename to example/asteroids.cpp diff --git a/examples/core_api.cpp b/example/core_api.cpp similarity index 100% rename from examples/core_api.cpp rename to example/core_api.cpp diff --git a/examples/custom_rtti.cpp b/example/custom_rtti.cpp similarity index 100% rename from examples/custom_rtti.cpp rename to example/custom_rtti.cpp diff --git a/examples/default_error_handler.cpp b/example/default_error_handler.cpp similarity index 100% rename from examples/default_error_handler.cpp rename to example/default_error_handler.cpp diff --git a/examples/deferred_custom_rtti.cpp b/example/deferred_custom_rtti.cpp similarity index 100% rename from examples/deferred_custom_rtti.cpp rename to example/deferred_custom_rtti.cpp diff --git a/examples/dl.hpp b/example/dl.hpp similarity index 100% rename from examples/dl.hpp rename to example/dl.hpp diff --git a/examples/dl_main.cpp b/example/dl_main.cpp similarity index 100% rename from examples/dl_main.cpp rename to example/dl_main.cpp diff --git a/examples/dl_shared.cpp b/example/dl_shared.cpp similarity index 100% rename from examples/dl_shared.cpp rename to example/dl_shared.cpp diff --git a/examples/friendship.cpp b/example/friendship.cpp similarity index 100% rename from examples/friendship.cpp rename to example/friendship.cpp diff --git a/examples/friendship_across_namespaces.cpp b/example/friendship_across_namespaces.cpp similarity index 100% rename from examples/friendship_across_namespaces.cpp rename to example/friendship_across_namespaces.cpp diff --git a/examples/headers_namespaces/CMakeLists.txt b/example/headers_namespaces/CMakeLists.txt similarity index 100% rename from examples/headers_namespaces/CMakeLists.txt rename to example/headers_namespaces/CMakeLists.txt diff --git a/examples/headers_namespaces/animal.hpp b/example/headers_namespaces/animal.hpp similarity index 100% rename from examples/headers_namespaces/animal.hpp rename to example/headers_namespaces/animal.hpp diff --git a/examples/headers_namespaces/cat.cpp b/example/headers_namespaces/cat.cpp similarity index 100% rename from examples/headers_namespaces/cat.cpp rename to example/headers_namespaces/cat.cpp diff --git a/examples/headers_namespaces/cat.hpp b/example/headers_namespaces/cat.hpp similarity index 100% rename from examples/headers_namespaces/cat.hpp rename to example/headers_namespaces/cat.hpp diff --git a/examples/headers_namespaces/dog.cpp b/example/headers_namespaces/dog.cpp similarity index 100% rename from examples/headers_namespaces/dog.cpp rename to example/headers_namespaces/dog.cpp diff --git a/examples/headers_namespaces/dog.hpp b/example/headers_namespaces/dog.hpp similarity index 100% rename from examples/headers_namespaces/dog.hpp rename to example/headers_namespaces/dog.hpp diff --git a/examples/headers_namespaces/main.cpp b/example/headers_namespaces/main.cpp similarity index 100% rename from examples/headers_namespaces/main.cpp rename to example/headers_namespaces/main.cpp diff --git a/examples/headers_namespaces/main_unrelated_namespaces.cpp b/example/headers_namespaces/main_unrelated_namespaces.cpp similarity index 100% rename from examples/headers_namespaces/main_unrelated_namespaces.cpp rename to example/headers_namespaces/main_unrelated_namespaces.cpp diff --git a/examples/headers_namespaces/main_using_directive.cpp b/example/headers_namespaces/main_using_directive.cpp similarity index 100% rename from examples/headers_namespaces/main_using_directive.cpp rename to example/headers_namespaces/main_using_directive.cpp diff --git a/examples/hello_world.cpp b/example/hello_world.cpp similarity index 100% rename from examples/hello_world.cpp rename to example/hello_world.cpp diff --git a/examples/matrix.cpp b/example/matrix.cpp similarity index 100% rename from examples/matrix.cpp rename to example/matrix.cpp diff --git a/examples/next.cpp b/example/next.cpp similarity index 100% rename from examples/next.cpp rename to example/next.cpp diff --git a/examples/slides.cpp b/example/slides.cpp similarity index 100% rename from examples/slides.cpp rename to example/slides.cpp diff --git a/examples/synopsis.cpp b/example/synopsis.cpp similarity index 100% rename from examples/synopsis.cpp rename to example/synopsis.cpp diff --git a/examples/throw_error_handler.cpp b/example/throw_error_handler.cpp similarity index 100% rename from examples/throw_error_handler.cpp rename to example/throw_error_handler.cpp diff --git a/examples/virtual_.cpp b/example/virtual_.cpp similarity index 100% rename from examples/virtual_.cpp rename to example/virtual_.cpp diff --git a/examples/virtual_func.cpp b/example/virtual_func.cpp similarity index 100% rename from examples/virtual_func.cpp rename to example/virtual_func.cpp diff --git a/examples/virtual_ptr.cpp b/example/virtual_ptr.cpp similarity index 100% rename from examples/virtual_ptr.cpp rename to example/virtual_ptr.cpp