<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>A Proposal to add Classes and Functions Required for Dynamic Library Load</title>
		<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
		<meta http-equiv="Content-Language" content="en-us">

		<style type="text/css">
			.addition { color: green; }
			.right { text-align:right; }
			.changed-deleted { background-color: #CFF0FC ; text-decoration: line-through; display: none; }
			.addition.changed-deleted { color: green; background-color: #CFF0FC ; text-decoration: line-through; text-decoration: black double line-through; display: none; }
			.changed-added { background-color: #DFF0FC ;}
            pre { line-height: 1.2; font-size: 10pt; margin-top: 25px;}
            .desc { margin-left: 35px; margin-top: 10px; padding:0; white-space: normal; }
            body {max-width: 1024px; margin-left: 25px;}
            /*code {font-size: large; }*/
            .cppkeyword { color: blue; }
            .cppcomment { color: green; }
            .cppcomment > .cppkeyword{ color: green; }
            .cpptext { color: #2E8B57; }
		</style>

	</head>
	<body bgcolor="#ffffff">
		<address>Document number: P0275R3</address>
		<address>Project: Programming Language C++</address>
		<address>Audience: Library Evolution Working Group</address>
		<address>&nbsp;</address>
		<address>Antony Polukhin &lt;<a href="mailto:antoshkka@gmail.com">antoshkka@gmail.com</a>&gt;, &lt;<a href="mailto:antoshkka@yandex-team.ru">antoshkka@yandex-team.ru</a>&gt;</address>
		<address>&nbsp;</address>
		<address>Date: 2018-02-01</address>
		<h1>A Proposal to add Classes and Functions Required for Dynamic Library Load</h1>


<span class='changed-added'>Changes to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0275r1.html">P0275R1</a> and  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0275r2.html">P0275R2</a> are marked with blue.</span>
<input type="checkbox" id="show_deletions" onchange="show_hide_deleted()"> Show deleted lines.

<br><br><br><br>
<div class="changed-added">

<p class="right">“This is just a means to get a pointer to a function.”</p>
<p class="right"><i>― Ville Voutilainen</i></p>
</div>

		<h2>I. Introduction and Motivation</h2>


		<p>Adding a specific features to an existing software applications at
            runtime could be useful in many cases. Such extensions, or plugins,
            are usually implemented using shared library files (.dll,
            .so/Dynamic Shared Objects) loaded into the memory of program at runtime. Such trechique is called <b>Dynamic <span class='changed-deleted'>Library </span>
            Loading (D<span class='changed-deleted'>L</span>L)</b>.</p>
		<p>Current C++ Standard lacks support for Dynamic Library 
            Loading. This proposal attempts to fix that and provide a simple to
            use classes and functions for DL.</p>
		<p class="changed-added">A quick survey at one of <a href="https://habrahabr.ru/company/yandex/blog/323972/">the popular Russian IT sites</a> shows that ~41% of people use
		dynamic loading in company or their own projects. Any wrapper around platform specific DL involves multiple macro, reinterpret_casts,
	    work with platform specific decorations, and even UBs due to
		OS API designs. Examples: <a href="https://github.com/STEllAR-GROUP/hpx/blob/release/hpx/util/plugin/detail/dll_dlopen.hpp">HPX</a>, <a href="https://github.com/pocoproject/poco/tree/develop/Foundation/src">POCO (see SharedLibrary* files)</a>, <a href="https://github.com/qt/qtbase/blob/5.3/src/corelib/plugin/">Qt(see qlibrary_*.cpp files)</a>.
		</p>
		<p>This proposal is based on the <a href="https://github.com/boostorg/dll">Boost.DLL</a> library. <span class="changed-added">Unlike many other libraries the Boost.DLL
		does not force a specific type for the imported symbols, does not include project specific stuff into the classes. It's just a
		abstraction around platform specific calls that attempts to unify DL behavior.</span></p>


		<h2>II. Impact on the Standard</h2>
		<p>This proposal is a pure library extension. It does not propose changes to
			existing headers. <span class='changed-deleted'>It does not require any changes in the core
			language and it could be implemented in standard C++.</span>
		</p>
		<p class='changed-added'>This proposal <span class='changed-deleted'>tries hard to be</span><span class='changed-added'>is</span> a library only extension and avoids adding a description of shared libraries machinery as much as possible.
		EWG has to decide:</p>
		<ul class='changed-added'>
		    <li>is it acceptable to describe usage of shared library files without any mention of how to construct them?</li>
		    <li>is it acceptable to have an unspecified behavior for DLL's TLS, globals, ADL, exceptions, ODR violations, global allocators?</li>
		</ul>
		<p class='changed-added'>EWG voted on "Add D<span class='changed-deleted'>L</span>L support to standard library?" in Albuquerque: 6 | 6 | 4 | 1 | 1, asked to embed feedback and send the proposal to LEWG.<p>

		<h2>III. Design Decisions</h2>
		<h3>A. Usage of <code>std::filesystem::path</code></h3>
		<p>To simplify library usage <code>std::filesystem::path</code> is used for specifying paths . All the <code>path</code> related overhead is minor,
            comparing to the time of loading shared library file into the memory of program or getting information about shared library file location.</p>
		<h3>B. Stick to the Filesystem error reporting scheme.</h3>
		<p>Provide two overloads for some functions, one that throws an exception to report system errors, and another that sets an <code>error_code</code>. This supports two common use cases:</p>
            <ul>
                <li>Uses where shared library file related system errors are truly exceptional and indicate a serious failure.</li>
                <li>Uses where shared library file related errors are routine and do not necessarily represent failure.</li>
            </ul>
		<h3>C. Do not take care of mangling.</h3>
		<p>C++ symbol mangling depend on compiler and platform. Existing attempts to get mangled symbol by unmangled name
        result in significant complexity and memory usage growth and overall slowdown of getting symbol from shared library file.
        </p>
        <pre>[ Example:
    // Loading a shared library file with mangled symbols
    mangled_library lib("libmycpp.so");

    // Attempt to get function "foo::bar" with signature void(int)
    lib.get&lt;void(int)&gt;("foo::bar");

    // The problem is that we do not know what `foo::bar` is:
    // * `foo` could be a class and `bar` could be a static member function
    // * `foo` could be a struct and `bar` could be a static member function
    // * `foo` could be a namespace and `bar` could be function in that namespace
    //
    // We also do not know the calling convention for `foo` and it's noexcept specification.
    //
    // Mangling of `foo::bar` depends on all the knowledge from above, so we are either forced to
    // mangle and try to obtain all the available combinations; or we need to investigate all the
    // symbols exported by "libmycpp.so" shared library file and find a best match.
- end example ]</pre>
            <p>While no good solution was found for obtaining mangled 
                symbol by unmangled name, this proposal concentrates on obtaining symbols 
                by exact name match.</p>
		<h3 class="changed-deleted">D. Provide functions for simple usage.</h3>
			<p class="changed-deleted">Keeping a shared library file loaded in memory of program while using the symbol obtained from shared library file could be
            hard and error prone for some users. For the simplicity of those users, <code>import</code>
            functions were provided. Those functions return a symbol 
            wrapped in a helper class along with an instance of <code>shared_library</code>. In that way while
            returned value in in scope, the shared
            library file won't be unloaded from program memory, so the user does not need to take
            care of shared library file lifetime in program memory.</p>
		<h3 class="changed-added">D. Drop the <code>import</code> function form Boost.DLL.</h3>
			<p class="changed-added">While those function could simplify code development for some users, they are simple to missuse:</p>
			<pre class="changed-added"><code>
try {
    auto f = dll::import&lt;int()&gt;(path_to_pugin, "function");
    f();
    // `f` goes out of scope along, plugin is unloaded, the exception::what() code is unreachable
} catch (const std::exception&amp; e) {
    std::cerr &lt;&lt; e.what();
}
            </code></pre>
		<h3>E. Do not search libraries in system specific paths by default.</h3>
			<p>Searching paths for a specified shared library file may affect load times and 
            make the proposed wording less efficient. It is assumed to be the most 
            common case, that
            user exactly knows were the desired shared library file is
            located and provides either absolute or relative to current
            directory path. For that case searching
            system specific paths affects performance and increases the 
            chance of finding wrong shared library file with the same name. Because some 
            operating systems search
            system paths even if relative path is provided, the 
            requirement to not do that is implicitly described in proposed wording. <span class="changed-added">That OS specific logic could be avoided by implicitly converting relative paths to absolute.</span></p>
		<h3>F. Minimal modifications for the N4687 wording.</h3>
        <p>There have been D<span class='changed-deleted'>L</span>L related proposals:</p>
        <ul>
        <li><a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2002/n1400.html">N1400: Toward standardization of dynamic libraries</a></li>
        <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1418.html">N1418: Dynamic Libraries in C++</a></li>
        <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1428.html">N1428: Draft Proposal for Dynamic Libraries in C++</a></li>
        <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1496.html">N1496: Draft Proposal for Dynamic Libraries in C++ (Revision 1)</a></li>
        <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1976.html">N1976: Dynamic Shared Objects: Survey and Issues</a></li>
        <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2015.pdf" >N2015: Plugins in C++</a></li>
        <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2407.html">N2407: C++ Dynamic Library Support</a></li>
        </ul>

        <p>The proposal you're reading attempts to avoid issues of the proposals from above, minifying the changes to the N4687 wording. The proposal you're reading:</p>
        <ul>
        <li>is a pure library extension (does not modify Basic Concepts [basic] and does not add new keywords)</li>
        <li>does not add platform requirement for shared libraries support</li>
        </ul>

        <h3 class="changed-added">G. Overloads take <code>const char*</code> and <code>const string&amp;</code>, not <code>string_view</code>.</h3>
        <p class="changed-added">OS specific API usually accepts symbol name as a zero terminated char array. <code>string_view</code> has no zero termination
        guarantee so it requires copying of the input parameter and zero termination. <code>char*</code> and <code>string&amp;</code> is a more efficient API design.</p>

		<h2>IV. Proposed wording relative to N4687</h2>

<h3>?? Dynamic <span class='changed-deleted'>library</span> loading support library<span class="right">[d<span class='changed-deleted'>l</span>l]</span></h3>
<h4>??.1 General <span class="right">[d<span class='changed-deleted'>l</span>l.general]</span></h4>
<p>
    'Dynamic loading' is a runtime mechanism to load shared library file into the memory of current program <span class="changed-added">at any point of <code>main</code>[basic.start.main] execution</span>,
    retrieve the addresses of functions and objects contained in the shared library file, execute those functions or access those objects,
    unload the shared library file from memory.
</p>
<p>
    'Shared library file' is a file containing set of objects and functions available for use at program startup or at runtime.
</p>
<p>
    <span class="changed-deleted">Headers &lt;experimental/d<span class='changed-deleted'>l</span>l&gt; and &lt;experimental/import&gt;
    define classes and functions suitable for dynamic library load. For
    those headers</span><span class="changed-added">Header &lt;experimental/d<span class='changed-deleted'>l</span>l&gt;
    defines classes and functions suitable for dynamic loading. For
    that header</span> term 'symbol' relates to a
    function, reference, class member or object that can be obtained from shared library file at runtime.
    Term 'symbol name' relates to a character identifier of a symbol, using
    which symbol can be obtained from shared library file. <i class="changed-added">[ Note:</i> For symbols declared with <code>extern
    "C"</code> in code of shared library file, 'symbol name' is the name of the
    entity. 'symbol name' for entities without <code>extern "C"</code> are unspecified. <i  class="changed-deleted">[ Note:</i> Typically symbol names of those entities are mangled entity names<i> — end note ]</i>.
</p>

<h4>??.2 Error reporting <span class="right">[d<span class='changed-deleted'>l</span>l.errors]</span></h4>
<p>
    Functions not having an argument of type <code>error_code&amp;</code> report errors as follows, unless otherwise specified:</p>
    <ul>
    <li>When a call by the implementation to an operating system or other underlying API results in an error that
    prevents the function from meeting its specifications, an exception of type system_error is thrown.</li>

    <li>Failure to allocate storage is reported by throwing an exception as described in the C++ standard,
    20.5.5.12[res.on.exception.handling].</li>

    <li>Destructors throw nothing.</li>
    </ul>

    Functions having an argument of type <code>error_code&amp;</code> report errors as follows, unless otherwise specified:
    <ul>
    <li>If a call by the implementation to an operating system or other underlying API results in an 
    error that prevents the function from meeting its specifications, the <code>error_code&amp;</code> argument is set as
    appropriate for the specific error. Otherwise, <code>clear()</code> is called on the <code>error_code&amp;</code> argument.</li>

    <li>Failure to allocate storage is reported by throwing an exception
         as described in the C++ standard, 20.5.5.12
        [res.on.exception.handling].</li>
    </ul>


<h4>??.3 Header &lt;experimental/d<span class='changed-deleted'>l</span>l&gt; <span class="right">[d<span class='changed-deleted'>l</span>l.d<span class='changed-deleted'>l</span>l]</span></h4>
<pre>namespace std {
  namespace experimental {
  inline namespace d<span class='changed-deleted'>l</span>l_v1 {
<span class="changed-deleted">
    // shared library file load modes
    enum class dll_mode {
        default_mode,
        dont_resolve_dll_references,    // DONT_RESOLVE_DLL_REFERENCES
        load_ignore_code_authz_level,   // LOAD_IGNORE_CODE_AUTHZ_LEVEL
        rtld_lazy,                      // RTLD_LAZY
        rtld_now,                       // RTLD_NOW
        rtld_global,                    // RTLD_GLOBAL
        rtld_local,                     // RTLD_LOCAL
        rtld_deepbind,                  // RTLD_DEEPBIND
        append_decorations,                // See [dll.dll_mode]
        search_system_directories       // See [dll.dll_mode]
    };

    constexpr dll_mode  operator| (dll_mode lhs, dll_mode rhs)  noexcept;
    constexpr dll_mode&amp; operator|=(dll_mode&amp; lhs, dll_mode rhs) noexcept;
    constexpr dll_mode  operator&amp; (dll_mode lhs, dll_mode rhs)  noexcept;
    constexpr dll_mode&amp; operator&amp;=(dll_mode&amp; lhs, dll_mode rhs) noexcept;
    constexpr dll_mode  operator^ (dll_mode lhs, dll_mode rhs)  noexcept;
    constexpr dll_mode&amp; operator^=(dll_mode&amp; lhs, dll_mode rhs) noexcept;
    constexpr dll_mode&amp; operator~ (dll_mode&amp; lhs) noexcept;
</span>
    // class to work with shared library files
    class shared_library;

    bool operator==(const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;
    bool operator!=(const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;
    bool operator&lt; (const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;
    bool operator&gt; (const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;
    bool operator&lt;=(const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;
    bool operator&gt;=(const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;

    // free functions
    template&lt;class T&gt;
    filesystem::path symbol_location(const T&amp; symbol, error_code&amp; ec);
    template&lt;class T&gt;
    filesystem::path symbol_location(const T&amp; symbol);

    filesystem::path this_line_location(error_code&amp; ec);
    filesystem::path this_line_location();

    filesystem::path program_location(error_code&amp; ec);
    filesystem::path program_location();

  }
  }

  // support
  template &lt;class T&gt; struct hash;
  template &lt;&gt; struct hash&lt;experimental::shared_library&gt;;<span class="changed-deleted">
  template &lt;&gt; struct hash&lt;experimental::d<span class='changed-deleted'>l</span>l_mode&gt;;</span>
}

</pre>
<div class="changed-deleted">
<p>
The value of each enum <code>d<span class='changed-deleted'>l</span>l_mode</code> constant shall be the same as the value 
of the macro shown in the above synopsis if that macro is available on 
the platform or 0 otherwise.
</p>


<h4>31.3.1.1 d<span class='changed-deleted'>l</span>l_mode operators <span class="right">[d<span class='changed-deleted'>l</span>l.d<span class='changed-deleted'>l</span>l_mode.operators]</span></h4>
<pre>constexpr d<span class='changed-deleted'>l</span>l_mode  operator| (d<span class='changed-deleted'>l</span>l_mode lhs, d<span class='changed-deleted'>l</span>l_mode rhs)  noexcept;
constexpr d<span class='changed-deleted'>l</span>l_mode&amp; operator|=(d<span class='changed-deleted'>l</span>l_mode&amp; lhs, d<span class='changed-deleted'>l</span>l_mode rhs) noexcept;
constexpr d<span class='changed-deleted'>l</span>l_mode  operator&amp; (d<span class='changed-deleted'>l</span>l_mode lhs, d<span class='changed-deleted'>l</span>l_mode rhs)  noexcept;
constexpr d<span class='changed-deleted'>l</span>l_mode&amp; operator&amp;=(d<span class='changed-deleted'>l</span>l_mode&amp; lhs, d<span class='changed-deleted'>l</span>l_mode rhs) noexcept;
constexpr d<span class='changed-deleted'>l</span>l_mode  operator^ (d<span class='changed-deleted'>l</span>l_mode lhs, d<span class='changed-deleted'>l</span>l_mode rhs)  noexcept;
constexpr d<span class='changed-deleted'>l</span>l_mode&amp; operator^=(d<span class='changed-deleted'>l</span>l_mode&amp; lhs, d<span class='changed-deleted'>l</span>l_mode rhs) noexcept;
constexpr d<span class='changed-deleted'>l</span>l_mode  operator~ (d<span class='changed-deleted'>l</span>l_mode&amp; lhs) noexcept;</pre>
    <div class="desc"><i>Effects:</i> Converts parameters to unsigned integral type capable of storing them, applies a corresponding
    binary operator and returns the result as <code>d<span class='changed-deleted'>l</span>l_mode</code>.</div>

<h4>31.3.1.2 d<span class='changed-deleted'>l</span>l_mode hash support<span class="right">[d<span class='changed-deleted'>l</span>l.d<span class='changed-deleted'>l</span>l_mode.hash]</span></h4>
<pre>template &lt;&gt; struct hash&lt;experimental::d<span class='changed-deleted'>l</span>l_mode&gt;;
</pre>
<p>
    The specialization is enabled (20.14.14).
</p>

</div>

<h4>??.4 Class shared_library <span class="right">[d<span class='changed-deleted'>l</span>l.shared_library]</span></h4>
<p>
    The class <code>shared_library</code> provides means to load shared library file into the memory of program,
    check that shared library file exports symbol with specified symbol name and obtain that
    symbol.
</p>
<p>
    <code>shared_library</code> instances share reference count to an actual shared library file loaded in memory
    of current program, so it is safe and memory efficient to have multiple instances
    of <code>shared_library</code> referencing the same shared library file even if those instances
    were loaded in memory using different paths (relative and absolute) referencing the
    same shared library file.
</p>
<p>
    <i>[ Note:</i>
    It <span class="changed-deleted">must be</span><span class="changed-added">is</span> safe to concurrently load shared library files into memory of program, unload and get symbols from
    any shared library files using different <code>shared_library</code> instances. If current
    platform does
    not guarantee safe concurrent work with shared library files, calls to <code>shared_library</code> functions  <span class="changed-deleted">must be</span><span class="changed-added">are</span> serialized by <code>shared_library</code> implementation.
    <i>— end note ]</i>
</p>
<p>
    <i>[ Note:</i>
    Constructors, comparisons and <code>reset()</code> functions that accept <code>nullptr_t</code> are not provided because that may cause confusion:
    some of the platforms provide interfaces for shared library files that accept <code>nullptr_t</code> to get a handler to the current program.
    <i>— end note ]</i>
</p>
<pre>namespace std {
  namespace experimental {
  inline namespace d<span class='changed-deleted'>l</span>l_v1 {

    class shared_library {
    public:
      using native_handle_type = <i>platform-specific</i>;
<span class="changed-added">
      // shared library file load modes
      using d<span class='changed-deleted'>l</span>l_mode = <i>T1</i>;
      static constexpr d<span class='changed-deleted'>l</span>l_mode default_mode;
      static constexpr d<span class='changed-deleted'>l</span>l_mode rtld_lazy;
      static constexpr d<span class='changed-deleted'>l</span>l_mode rtld_now;
      static constexpr d<span class='changed-deleted'>l</span>l_mode rtld_global;
      static constexpr d<span class='changed-deleted'>l</span>l_mode rtld_local;
      static constexpr d<span class='changed-deleted'>l</span>l_mode add_decorations;
      static constexpr d<span class='changed-deleted'>l</span>l_mode search_system_directories;</span>

      // construct/copy/destruct
      shared_library() noexcept;
<span class="changed-deleted">
      shared_library(const shared_library&amp; lib);
      shared_library(const shared_library&amp; lib, error_code&amp; ec);
</span>      shared_library(shared_library&amp;&amp; lib) noexcept;
      <span class="changed-deleted">explicit shared_library(const filesystem::path&amp; library_path, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode);</span>
      <span class="changed-added">explicit shared_library(const filesystem::path&amp; library_path);
      shared_library(const filesystem::path&amp; library_path, d<span class='changed-deleted'>l</span>l_mode mode);</span>
      shared_library(const filesystem::path&amp; library_path, error_code&amp; ec<span class="changed-deleted">, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode</span>);
      shared_library(const filesystem::path&amp; library_path, d<span class='changed-deleted'>l</span>l_mode mode, error_code&amp; ec);
      ~shared_library();

      // public member functions
<span class="changed-deleted">
      shared_library&amp; assign(const shared_library&amp; lib, error_code&amp; ec);
      shared_library&amp; assign(const shared_library&amp; lib);

      shared_library&amp; operator=(const shared_library&amp; lib);
</span>      shared_library&amp; operator=(shared_library&amp;&amp; lib) noexcept;
<span class="changed-deleted">
      void load(const filesystem::path&amp; library_path, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode);
      void load(const filesystem::path&amp; library_path, error_code&amp; ec, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode);
      void load(const filesystem::path&amp; library_path, d<span class='changed-deleted'>l</span>l_mode mode, error_code&amp; ec);

</span>      void reset() noexcept;
      explicit operator bool() const noexcept;
<span class="changed-deleted">
      bool has(const char* symbol_name) const noexcept;
      bool has(const string&amp; symbol_name) const noexcept;
</span><span class="changed-added">
      template &lt;typename SymbolT&gt;
      SymbolT* get_if(const char* symbol_name) const noexcept;

      template &lt;typename SymbolT&gt;
      SymbolT* get_if(const string&amp; symbol_name) const noexcept;
</span>

      template &lt;typename SymbolT&gt;
      <span class="changed-added">SymbolT&amp;</span><span class="changed-deleted">auto</span> get(const char* symbol_name) const<span class="changed-deleted">
        -&gt; conditional_t&lt;is_member_pointer_v&lt;SymbolT&gt;, SymbolT, add_lvalue_reference_t&lt;SymbolT&gt;&gt;</span>;

      template &lt;typename SymbolT&gt;
      <span class="changed-added">SymbolT&amp;</span><span class="changed-deleted">auto</span> get(const string&amp; symbol_name) const<span class="changed-deleted">
        -&gt; conditional_t&lt;is_member_pointer_v&lt;SymbolT&gt;, SymbolT, add_lvalue_reference_t&lt;SymbolT&gt;&gt;</span>;

      native_handle_type native_handle() const noexcept;
<span class="changed-deleted">
      filesystem::path location() const;
      filesystem::path location(error_code&amp; ec) const;
</span>
      // public static member functions
      static constexpr bool platform_supports_dl<span class='changed-deleted'>l</span>() noexcept;
      static constexpr bool platform_supports_dl<span class='changed-deleted'>l</span>_of_program() noexcept;
    };

  }
  }
}
</pre>
<p class="changed-added"><code>shared_library</code> defines member bitmask type <code>d<span class='changed-deleted'>l</span>l_mode</code>.</p>

<h4>??.4.1 Type d<span class='changed-deleted'>l</span>l_mode <span class="right">[d<span class='changed-deleted'>l</span>l.shared_library.d<span class='changed-deleted'>l</span>l_mode]</span></h4>
<pre>using d<span class='changed-deleted'>l</span>l_mode = <i>T1</i>;</pre>
<p>
    <span class="changed-deleted">Enum</span><span class="changed-added">Bitmask type</span> <code>d<span class='changed-deleted'>l</span>l_mode</code> provides modes for searching the shared library file and platform specific modes for loading the shared library file in memory of program.
    <i>[ Note:</i> library users may extend available modes by
    casting the required platform specific mode to d<span class='changed-deleted'>l</span>l_mode: <i>[ Example:</i> <code>static_cast&lt;d<span class='changed-deleted'>l</span>l_mode&gt;(RTLD_NODELETE); </code><i> — end example ] — end note ]</i></p>

<p class="changed-deleted">
    Each of system family
    provides own modes, flags not supported by a particular platform <span class="changed-deleted">must be</span><span class="changed-added">are</span>
    set to 0. Special modes are listened below:
</p>

<h4>??.4.2 d<span class='changed-deleted'>l</span>l_mode constants <span class="right">[d<span class='changed-deleted'>l</span>l.shared_library.d<span class='changed-deleted'>l</span>l_const]</span></h4>
<pre><span class="changed-deleted">append</span><span class="changed-added">add</span>_decorations</pre>
    <div class="desc"><i>Effects:</i> A<span class="changed-deleted">ppen</span><span class="changed-added">d</span>ds a platform specific extensions and prefixes to shared library filename before trying to load it into program memory.
    If load attempts fail, loads with exactly specified name.</div>
    <div class="desc"><i>Value:</i> Any value that can not be received by applying binary OR to any set of modes from <code>d<span class='changed-deleted'>l</span>l_mode</code></div>
    <div class="desc"><i>[ Example:</i></div>
<pre>        // Attempts to open
        //      `./my_plugins/plugin1.d<span class='changed-deleted'>l</span>l` and `./my_plugins/libplugin1.d<span class='changed-deleted'>l</span>l` on Windows
        //      `./my_plugins/libplugin1.so` on Linux
        //      `./my_plugins/libplugin1.dylib` and `./my_plugins/libplugin1.so` on MacOS.
        // If that fails, loads `./my_plugins/plugin1`
        shared_library lib("./my_plugins/plugin1", d<span class='changed-deleted'>l</span>l_mode::<span class="changed-deleted">append</span><span class="changed-added">add</span>_decorations);
</pre>
<div class="desc"><i>- end example ]</i></div>

<div class="changed-added">
<pre>rtld_lazy</pre>
    <div class="desc"><i>Effects:</i> As if applying RTLD_LAZY on POSIX.</div>
    <div class="desc"><i>Value:</i> <code>0</code> if platform does not have RTLD_LAZY equivalent. Platform specific value of RTLD_LAZY equivalent otherwise.</div>

<pre>rtld_now</pre>
    <div class="desc"><i>Effects:</i> As if applying RTLD_NOW on POSIX.</div>
    <div class="desc"><i>Value:</i> <code>0</code> if platform does not have RTLD_NOW equivalent. Platform specific value of RTLD_NOW equivalent otherwise.</div>
<pre>rtld_global</pre>
    <div class="desc"><i>Effects:</i> As if applying RTLD_GLOBAL on POSIX.</div>
    <div class="desc"><i>Value:</i> <code>0</code> if platform does not have RTLD_GLOBAL equivalent. Platform specific value of RTLD_GLOBAL equivalent otherwise.</div>
<pre>rtld_local</pre>
    <div class="desc"><i>Effects:</i> As if applying RTLD_LOCAL on POSIX.</div>
    <div class="desc"><i>Value:</i> <code>0</code> if platform does not have RTLD_LOCAL equivalent. Platform specific value of RTLD_LOCAL equivalent otherwise.</div>

</div>

<pre>default_mode</pre>
    <div class="desc"><i>Value:</i> <code>rtld_lazy | rtld_local</code>.</div>

<pre>search_system_directories</pre>
    <div class="desc"><i>Value:</i> Any value that can not be received by applying binary OR to any set of modes from <code>d<span class='changed-deleted'>l</span>l_mode</code></div>
    <div class="desc"><i>Effects:</i> Allows loading of shared library files from system specific shared library file directories [fs.def.directory]
    along with loading shared library files from current directory.</div>

<h4>??.4.3 shared_library constructors <span class="right">[d<span class='changed-deleted'>l</span>l.shared_library.constr]</span></h4>
<pre>shared_library() noexcept;</pre>
    <div class="desc"><i>Effects:</i> Creates <code>shared_library</code> that does not reference any shared library file.</div>
    <div class="desc"><i>Postconditions:</i> <code>*this</code> is <code>false</code>.</div>
<div class="changed-deleted">
<pre>shared_library(const shared_library&amp; lib);
shared_library(const shared_library&amp; lib, error_code&amp; ec);</pre>
    <div class="desc"><i>Effects:</i> Makes <code>*this</code> reference the same shared library file that is referenced by <code>lib</code> or if <code>lib</code> does not reference shared library file
    sets <code>*this</code> to default constructed state.</div>
    <div class="desc"><i>Postconditions:</i> <code>lib == *this</code></div>
    <div class="desc"><i>Throws:</i> As specified in [d<span class='changed-deleted'>l</span>l.errors]</div>
</div>
<pre>shared_library(shared_library&amp;&amp; lib) noexcept;</pre>
    <div class="desc"><i>Effects:</i> Assigns the state of <code>lib</code> to <code>*this</code> and sets <code>lib</code> to a default constructed state.</div>
    <div class="desc"><i>Remarks:</i> Does not invalidate symbols previously obtained from <code>lib</code>.</div>
    <div class="desc"><i>Postconditions:</i> <code>lib</code> is <code>false</code>, <code>*this</code> is <code>true</code>.</div>

<pre><span class="changed-deleted">explicit shared_library(const filesystem::path&amp; library_path, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode);</span>
<span class="changed-added">explicit shared_library(const filesystem::path&amp; library_path);
shared_library(const filesystem::path&amp; library_path, d<span class='changed-deleted'>l</span>l_mode mode);</span>
shared_library(const filesystem::path&amp; library_path, error_code&amp; ec<span class="changed-deleted">, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode</span>);
shared_library(const filesystem::path&amp; library_path, d<span class='changed-deleted'>l</span>l_mode mode, error_code&amp; ec);</pre>
    <div class="desc"><i>Effects:</i> If the shared library file specified by <code>library_path</code> is already loaded in memory of current program
    makes <code>*this</code> reference the previously loaded shared library file.
    Otherwise loads a shared library file by specified path with a specified mode into the memory of current program,
    executes all the platform specific initializations.</div>

    <div class="desc">References current program if
    absolute or relative path to the program was provided as
    <code>library_path</code> and <code>platform_supports_dl<span class="changed-deleted">l</span>_of_program()</code> is <code>true</code>.</div>
    <div class="desc">Loads shared library file with changed name and applied extension only if <code>(mode &amp; 
    d<span class='changed-deleted'>l</span>l_mode::<span class="changed-deleted">append</span><span class="changed-added">add</span>_decorations)</code> is not 0.
    <span class="changed-deleted"> Must attempt to load</span><span class="changed-added">Loads</span> a shared library file from system specific shared library file
    directories only if <code>library_path</code> contains only shared library filename and
    <code>(mode &amp; d<span class='changed-deleted'>l</span>l_mode::search_system_directories)</code> is not 0. During loads
    from system
    specific directories file name modification rules from above apply. If
    with <code>d<span class='changed-deleted'>l</span>l_mode::search_system_directories</code> more than one
    shared library file has the same base name and extension, the function
    loads in memory any first matching shared library file.
    If <code>(mode &amp; d<span class='changed-deleted'>l</span>l_mode::search_system_directories)</code> is 0, then any 
    relative path or path that contains only filename <span class="changed-deleted">must be</span><span class="changed-added">is</span> treated as a
    path in current working directory.</div>

    <div class="desc">Library open mode is equal to <code>(mode &amp; 
    ~d<span class='changed-deleted'>l</span>l_mode::search_system_directories &amp; ~d<span class='changed-deleted'>l</span>l_mode::<span class="changed-deleted">append</span><span class="changed-added">add</span>_decorations)</code>
    converted to a platform specific
    type representing shared library file load modes and adjusted to satisfy the 
    <code>d<span class='changed-deleted'>l</span>l_mode::search_system_directories</code> requirements from above. If mode is
    invalid for current platform, attempts to adjust the mode by 
    applying <code>d<span class='changed-deleted'>l</span>l_mode::rtld_lazy</code>
    and reports error if resulting mode
    is invalid. <i>[ Example:</i> If mode on POSIX was set to <code>rtld_local</code>, then it will be adjusted
    to <code>rtld_lazy | rtld_local</code>. <i>- end example ]</i></div>

    <div class="desc"><i>Throws:</i> As specified in [d<span class='changed-deleted'>l</span>l.errors]</div>

    <div class="desc changed-deleted"><i>Effects:</i> Same as calling <code>shared_library::load()</code> with same parameters.</div>
    <div class="desc changed-deleted"><i>Throws:</i> As specified in [d<span class='changed-deleted'>l</span>l.errors].</div>


<h4>??.4.4 shared_library destructor <span class="right">[d<span class='changed-deleted'>l</span>l.shared_library.destr]</span></h4>
<pre>~shared_library();</pre>
<div class="desc">
    <i>Effects:</i> Destroys the <code>shared_library</code> by calling <code>reset()</code>.<span class="changed-deleted"> If
    the shared library file is referenced by different instances of
    <code>shared_library</code>,
    the shared library file won't be unloaded until there is at least one 
    instance of <code>shared_library</code> referencing it.</span>
</div>


<div class="changed-deleted">
<h4>??.4.5 shared_library assignment <span class="right">[d<span class='changed-deleted'>l</span>l.shared_library.assign]</span></h4>
<pre>shared_library&amp; operator=(const shared_library&amp; lib);</pre>
    <div class="desc"><i>Effects:</i> Same as calling <code>assign(lib)</code></div>
    <div class="desc"><i>Returns:</i> <code>*this</code></div>
</div>
<pre>shared_library&amp; operator=(shared_library&amp;&amp; lib) noexcept;</pre>
    <div class="desc"><i>Effects:</i> If <code>*this</code> then calls
 <code>reset()</code>. Assigns the state of <code>lib</code> to <code>*this</code> and sets <code>lib</code> 
to a default constructed state.</div>
    <div class="desc"><i>Remarks:</i> Does not invalidate symbols previously obtained from <code>lib</code>.</div>
    <div class="desc"><i>Postconditions:</i> <code>lib</code> is <code>false</code>, <code>*this</code> is <code>true</code>.</div>
    <div class="desc"><i>Returns:</i> <code>*this</code></div>


<h4>??.4.6 shared_library members<span class="right">[d<span class='changed-deleted'>l</span>l.shared_library.member]</span></h4>
<div class="changed-deleted">
<pre>shared_library&amp; assign(const shared_library&amp; lib, error_code&amp; ec);
shared_library&amp; assign(const shared_library&amp; lib);</pre>
    <div class="desc"><i>Effects:</i> If <code>*this</code>, then calls <code>reset()</code>.
    Makes <code>*this</code> reference the same shared library file as <code>lib</code>.</div>
    <div class="desc"><i>Postconditions:</i> <code>lib.location() == location()</code>, <code>lib == *this</code></div>
    <div class="desc"><i>Returns:</i> <code>*this</code></div>
    <div class="desc"><i>Throws:</i> As specified in [d<span class='changed-deleted'>l</span>l.errors]</div>
</div>
<pre class="changed-deleted">void load(const filesystem::path&amp; library_path, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode);
void load(const filesystem::path&amp; library_path, error_code&amp; ec, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode);
void load(const filesystem::path&amp; library_path, d<span class='changed-deleted'>l</span>l_mode mode, error_code&amp; ec);</pre>

<pre>void reset() noexcept;</pre>
    <div class="desc"><i>Effects:</i> Sets <code>*this</code> to a default constructed state. If <code>*this</code> was the last instance of <code>shared_library</code> referencing the shared library file,
    then all the resources associated with shared library file shall be released.</div>
    <div class="desc"><i>Remarks:</i> Symbols obtained from shared library file remain valid <span class="changed-deleted">until</span><span class="changed-added">if</span> there is at least one instance of <code>shared_library</code> referencing the shared library file.</div>
    <div class="desc"><i>Postconditions:</i> <code>*this</code> is <code>false</code>.</div>

<pre>explicit operator bool() const noexcept;</pre>
    <div class="desc"><i>Returns:</i> <code>true</code> if <code>*this</code> references a shared library file.</div>

<pre class="changed-deleted">bool has(const char* symbol_name) const noexcept;
bool has(const string&amp; symbol_name) const noexcept;</pre>
    <div class="desc changed-deleted"><i>Returns:</i> <code>true</code> if <code>*this</code> references a shared library file and symbol symbol_name could be obtained from shared library file.</div>

<div class="changed-added">
<pre>template &lt;typename SymbolT&gt;
  SymbolT* get_if(const char* symbol_name) const noexcept;

template &lt;typename SymbolT&gt;
  SymbolT* get_if(const string&amp; symbol_name) const noexcept;</pre>
    <div class="desc"><i>Returns:</i> Pointer to symbol from shared library file that has the name <code>symbol_name</code>, <code>nullptr</code> otherwise.</div>
    <div class="desc"><i>Remarks:</i> It's the user responsibility to 
    provide valid <code>SymbolT</code> type for symbol. However implementations may 
    provide additional checks for
    matching <code>SymbolT</code> type and actual symbol type. <i>[ Note:</i> For
    example implementations
    may check that <code>SymbolT</code> is a function pointer and that
    symbol with <code>symbol_name</code> allows execution. <i>— end note ]</i></div>
</div>

<pre>template &lt;typename SymbolT&gt;
  SymbolT&amp; get(const char* symbol_name) const;

template &lt;typename SymbolT&gt;
  SymbolT&amp; get(const string&amp; symbol_name) const;</pre>
    <div class="desc"><i>Returns:</i> <code>*get_if&lt;SymbolT&gt;(symbol_name)</code>.</div>
    <div class="desc"><i>Throws:</i> <code>system_error</code> if symbol does not exist or if the shared library file was not loaded.</div>

<pre>native_handle_type native_handle() const noexcept;</pre>
    <div class="desc"><i>Returns:</i> Native handler of the loaded in memory shared library file or default constructed native_handle_type if *this does not reference a shared library file.
    <i>[ Note:</i> This member allow implementations to provide access to implementation details. Actual use of these members is inherently non-portable. <i>— end note ]</i>
</div>

<div class="changed-deleted">
<pre class="desc">filesystem::path location() const;
filesystem::path location(error_code&amp; ec) const;</pre>
    <div class="desc"><i>Returns:</i> Full path and name to the referenced shared library file,
    reports error if <code>*this</code> does not reference shared library file.</div>
    <div class="desc"><i>Throws:</i> As specified in [d<span class='changed-deleted'>l</span>l.errors]</div>
</div>

<h4>??.4.7 shared_library static members<span class="right">[d<span class='changed-deleted'>l</span>l.shared_library.static]</span></h4>

<pre>static constexpr bool platform_supports_dl<span class="changed-deleted">l</span>() noexcept;</pre>
    <div class="desc"><i>Returns:</i> true if platform supports loading of shared library files into the memory of program.
    [ Note: If this function returns <code>false</code>, then any attempt to load a shared library file will fail at runtime. This function could be used to ensure platform capabilities at
    compile time: <code>static_assert(shared_library::platform_supports_dl<span class="changed-deleted">l</span>(), "DL required for this program");</code> — end note ]</div>


<pre>static constexpr bool platform_supports_dl<span class="changed-deleted">l</span>_of_program() noexcept</pre>
    <div class="desc"><i>Returns:</i> <code>true</code> if according to platform capabilities <code>shared_library(program_location())</code> may succeed.</div>


<h4>??.4.8 shared_library free operators<span class="right">[d<span class='changed-deleted'>l</span>l.shared_library.operators]</span></h4>
<p>
    <code>shared_library</code> provides fast comparison operators that compare the referenced shared libraries file.
</p>
<pre>bool operator==(const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;</pre>
    <div class="desc"><i>Returns:</i> <code>lhs.native_handle() == rhs.native_handle()</code></div>

<pre>bool operator!=(const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;</pre>
    <div class="desc"><i>Returns:</i> <code>lhs.native_handle() != rhs.native_handle()</code></div>

<pre>bool operator&lt;(const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;</pre>
    <div class="desc"><i>Returns:</i> <code>lhs.native_handle() &lt; rhs.native_handle()</code></div>

<pre>bool operator&gt;(const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;</pre>
    <div class="desc"><i>Returns:</i> <code>lhs.native_handle() &gt; rhs.native_handle()</code></div>

<pre>bool operator&lt;=(const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;</pre>
    <div class="desc"><i>Returns:</i> <code>lhs.native_handle() &lt;= rhs.native_handle()</code></div>

<pre>bool operator&gt;=(const shared_library&amp; lhs, const shared_library&amp; rhs) noexcept;</pre>
    <div class="desc"><i>Returns:</i> <code>lhs.native_handle() &gt;= rhs.native_handle()</code></div>


<h4>??.4.9 shared_library hash support<span class="right">[d<span class='changed-deleted'>l</span>l.shared_library.hash]</span></h4>
<pre>template &lt;&gt; struct hash&lt;experimental::shared_library&gt;;</pre><p>
    <div class="desc">
        The specialization is enabled (23.14.15).
    </div>


<h4>??.5 Runtime path functions<span class="right">[d<span class='changed-deleted'>l</span>l.location]</span></h4>
<pre>template&lt;class T&gt;
filesystem::path symbol_location(const T&amp; symbol, error_code&amp; ec);
template&lt;class T&gt;
filesystem::path symbol_location(const T&amp; symbol);</pre>
    <div class="desc"><i>Returns:</i> Full path and name to shared library file or program that contains <code>symbol</code></div>
    <div class="desc"><i>Throws:</i> As specified in [d<span class='changed-deleted'>l</span>l.errors]</div>

<pre>filesystem::path this_line_location(error_code&amp; ec);
filesystem::path this_line_location();</pre>
    <div class="desc"><i>Returns:</i> Full path and name to shared library file or program that contains line of code in which <code>this_line_location()</code> was called</div>
    <div class="desc"><i>Throws:</i> As specified in [d<span class='changed-deleted'>l</span>l.errors]</div>

<pre>filesystem::path program_location(error_code&amp; ec);
filesystem::path program_location();</pre>
    <div class="desc"><i>Returns:</i> Full path and name to the current program.</div>
    <div class="desc"><i>Throws:</i> As specified in [d<span class='changed-deleted'>l</span>l.errors]</div>

<div class='changed-deleted'>

<h4>31.4 Header &lt;experimental/import&gt; <span class="right">[d<span class='changed-deleted'>l</span>l.import.header]</span></h4>
<pre>#include &lt;experimental/d<span class='changed-deleted'>l</span>l&gt;
#include &lt;type_traits&gt;
#include &lt;memory&gt;
#include &lt;functional&gt;

namespace std {
  namespace experimental {
  inline namespace d<span class='changed-deleted'>l</span>l_v1 {

    template &lt;typename SymbolT&gt;
    using imported_t = conditional_t&lt;is_object_v&lt;SymbolT&gt;, shared_ptr&lt;SymbolT&gt;, function&lt;SymbolT&gt;&gt;;

    // functions for importing a symbol
    template &lt;typename SymbolT&gt;
    imported_t&lt;SymbolT&gt; import(const filesystem::path&amp; library_path, const char* symbol_name, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode);

    template &lt;typename SymbolT&gt;
    imported_t&lt;SymbolT&gt; import(const filesystem::path&amp; library_path, const string&amp; symbol_name, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode);

    template &lt;typename SymbolT&gt;
    imported_t&lt;SymbolT&gt; import(const shared_library&amp; library, const char* symbol_name);

    template &lt;typename SymbolT&gt;
    imported_t&lt;SymbolT&gt; import(const shared_library&amp; library, const string&amp; symbol_name);

    template &lt;typename SymbolT&gt;
    imported_t&lt;SymbolT&gt; import(shared_library&amp;&amp; library, const char* symbol_name);

    template &lt;typename SymbolT&gt;
    imported_t&lt;SymbolT&gt; import(shared_library&amp;&amp; library, const string&amp; symbol_name);

  }
  }
}
</pre>

<p><code>import</code> functions are meant to simplify dynamic library loads of
    symbols by keeping shared library file loaded in program memory while imported symbol is in scope:</p>
<pre><i>[ Example:</i>
    // Code of "/plugin_directory/libplugin.so" contains extern "C" void foo_function(string&amp;&amp;)

    auto foo_function = import&lt;void(string&amp;&amp;)&gt;("/plugin_directory/libplugin.so", "foo_function");
    foo_function("Test");
<i>- end example ]</i></pre>


<h4>31.4.1 import functions <span class="right">[d<span class='changed-deleted'>l</span>l.import.func]</span></h4>
<pre>template &lt;typename SymbolT&gt;
imported_t&lt;SymbolT&gt; import(const filesystem::path&amp; library_path, const char* symbol_name, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode);

template &lt;typename SymbolT&gt;
imported_t&lt;SymbolT&gt; import(const filesystem::path&amp; library_path, const string&amp; symbol_name, d<span class='changed-deleted'>l</span>l_mode mode = d<span class='changed-deleted'>l</span>l_mode::default_mode);

template &lt;typename SymbolT&gt;
imported_t&lt;SymbolT&gt; import(const shared_library&amp; library, const char* symbol_name);

template &lt;typename SymbolT&gt;
imported_t&lt;SymbolT&gt; import(const shared_library&amp; library, const string&amp; symbol_name);

template &lt;typename SymbolT&gt;
imported_t&lt;SymbolT&gt; import(shared_library&amp;&amp; library, const char* symbol_name);

template &lt;typename SymbolT&gt;
imported_t&lt;SymbolT&gt; import(shared_library&amp;&amp; library, const string&amp; symbol_name);</pre>
    <div class="desc"><i>Effects:</i> Obtains a symbol with name <code>symbol_name</code> from shared library file and returns it wrapped in class that implements semantics
    of shared ownership of shared library file; the last remaining owner is responsible for releasing the resources associated with the
    shared library file. <code>mode</code> must be passed to <code>shared_library</code> constructor or <code>shared_library::load</code> function.</div>
    <div class="desc"><i>Remarks:</i> It's the user responsibility to provide valid <code>SymbolT</code> type for symbol.</div>
    <div class="desc"><i>Return type:</i> <code>imported_t&lt;SymbolT&gt;</code> that keeps an instance an of <code>shared_library</code> internally</div>
    <div class="desc"><i>Returns:</i> Variable that keeps <code>shared_library</code> and symbol and provides access to the symbol only.</div>
    <div class="desc"><i>Throws:</i> <code>system_error</code> if symbol does not exist or if failed to load the shared library file into the memory of program.</div>

</div>


		<h2>V. Feature-testing macro</h2>
		<p class="changed-deleted">For the purposes of SG10 it is sufficient to check for header
        &lt;experimental/dll&gt; or &lt;experimental/import&gt; using __has_include.
        </p>
        <p class="changed-added">For the purposes of SG10, we recommend the feature-testing macro name __cpp_lib_shared_library.</p>


		<h2>VI. Revision History</h2>
		<p class="changed-added">Revision 3:</p>
		<ul class="changed-added">
			<li>Changed Dynamic Library Load(DLL) term to Dynamic Loading (DL)</li>
			<li>Embedded EWG voting results</li>
			<li>Dropped copy constructors, assignment operators and assign functions of shared_library</li>
			<li>Dropped shared_library::location functions</li>
		</ul>
		<p class="changed-added">Revision 2:</p>
		<ul class="changed-added">
			<li>Added EWG questions</li>
			<li>Added motivation for not using <code>string_view</code></li>
			<li>Return pointer from get</li>
			<li>Some usage numbers and examples</li>
			<li>Specified and reduced load modes</li>
			<li>Fixed "must" usage in proposal</li>
			<li>Dropped <code>load()</code> functions</li>
			<li>Revised constructor overloads</li>
			<li>Dropped <code>import</code> functions</li>
			<li>Added feature testing macro</li>
			<li>"append_decorations" => "add_decorations"</li>
			<li><code>dl<span class='changed-deleted'>l</span>_mode</code> description rewritten</li>
			<li>Multiple minor improvements</li>
			<li>Rebased to N4687</li>
		</ul>
		<p>Revision 1:</p>
		<ul>
			<li>
				Rebased to N4618 and applied minor fixes
			</li>
		</ul>
		<p>Revision 0:</p>
		<ul>
			<li>
				Initial proposal
			</li>
		</ul>


		<h2>VII. References</h2>
		<p>[<a name="Boost.DLL">Boost.DLL</a>] Boost DLL library.
			Available online at <a href="https://github.com/boostorg/dll">https://github.com/boostorg/dll</a></p>
		<p>[<a name="N4618">N4618</a>] Working Draft, Standard for Programming Language C++.
			Available online at <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4618.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4618.pdf</a></p>


		<p>[<a name="N1400">N1400</a>] Toward standardization of dynamic libraries.
			Available online at <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2002/n1400.html">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2002/n1400.html</a></p>
		<p>[<a name="N1418">N1418</a>] Dynamic Libraries in C++.
			Available online at <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1418.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1418.html</a></p>
		<p>[<a name="N1428">N1428</a>] Draft Proposal for Dynamic Libraries in C++.
			Available online at <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1428.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1428.html</a></p>
		<p>[<a name="N1496">N1496</a>] Draft Proposal for Dynamic Libraries in C++ (Revision 1).
			Available online at <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1496.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1496.html</a></p>
		<p>[<a name="N1976">N1976</a>] Dynamic Shared Objects: Survey and Issues.
			Available online at <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1976.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1976.html</a></p>
		<p>[<a name="N2015">N2015</a>] Plugins in C++.
			Available online at <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2015.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2015.pdf</a></p>
		<p>[<a name="N2407">N2407</a>] C++ Dynamic Library Support.
			Available online at <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2407.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2407.html</a></p>
		<p>&nbsp;</p>

		<h2>VIII. Acknowledgements</h2>
		<p>Klemens Morgenstern highlighted some of the missing functionality 
        in Boost.DLL and provided implementation of mangled symbols load,
        that showed complexities of such approach. Renato Tegon Forti started the work on Boost.DLL and
        provided a lot of code, help and documentation for the Boost.DLL.</p>
        <p>Thanks to Tom Honermann for providing comments and recommendations.</p>



        <script type="text/javascript">
            function colorize_texts(texts) {
                for (var i = 0; i < texts.length; ++i) {
                    var text = texts[i].innerHTML;
                    text = text.replace(/namespace|enum|void|constexpr|extern|noexcept|bool|template|class |struct|auto|const|typename|explicit|public|private|operator|#include|char|typedef|static_assert|static_cast|static/g,"<span class='cppkeyword'>$&<\/span>");
                    text = text.replace(/\/\/[\s\S]+?\n/g,"<span class='cppcomment'>$&<\/span>");
                    //text = text.replace(/\"[\s\S]+?\"/g,"<span class='cpptext'>$&<\/span>");
                    texts[i].innerHTML = text;
                }
            }

            colorize_texts(document.getElementsByTagName("pre"));
            colorize_texts(document.getElementsByTagName("code"));

            function show_hide_deleted() {
                var to_change = document.getElementsByClassName('changed-deleted');
                for (var i = 0; i < to_change.length; ++i) {
                    to_change[i].style.display = (document.getElementById("show_deletions").checked ? 'inline' : 'none');
                }
            }
        </script>


</body></html>
