-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
36 changed files
with
859 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,19 @@ | ||
cmake_minimum_required(VERSION 3.14) | ||
find_package(proxy CONFIG REQUIRED) | ||
add_subdirectory(resource_dictionary) | ||
project(msft_proxy_samples) | ||
|
||
file(GLOB_RECURSE SOURCES "*.cpp") | ||
|
||
foreach(SOURCE ${SOURCES}) | ||
file(RELATIVE_PATH REL_PATH ${CMAKE_SOURCE_DIR} ${SOURCE}) | ||
get_filename_component(DIR ${REL_PATH} DIRECTORY) | ||
string(REPLACE "/" "_" DIR_UNDERSCORE ${DIR}) | ||
get_filename_component(EXECUTABLE_NAME ${SOURCE} NAME_WE) | ||
set(FULL_EXECUTABLE_NAME "${DIR_UNDERSCORE}_${EXECUTABLE_NAME}") | ||
add_executable(${FULL_EXECUTABLE_NAME} ${SOURCE}) | ||
target_link_libraries(${FULL_EXECUTABLE_NAME} PRIVATE msft_proxy) | ||
endforeach() | ||
|
||
if (MSVC) | ||
add_compile_options(/W4) | ||
else() | ||
add_compile_options(-Wall -Wextra -Wpedantic) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from PRO_DEF_FREE_DISPATCH.md. | ||
|
||
#include <iostream> | ||
#include <string> | ||
|
||
#include "proxy.h" | ||
|
||
PRO_DEF_FREE_DISPATCH(FreeToString, std::to_string, ToString); | ||
|
||
struct Stringable : pro::facade_builder | ||
::add_convention<FreeToString, std::string()> | ||
::build {}; | ||
|
||
int main() { | ||
pro::proxy<Stringable> p = pro::make_proxy<Stringable>(123); | ||
std::cout << ToString(*p) << "\n"; // Prints: "123" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from PRO_DEF_MEM_DISPATCH.md. | ||
|
||
#include <iostream> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include "proxy.h" | ||
|
||
PRO_DEF_MEM_DISPATCH(MemAt, at); | ||
|
||
struct Dictionary : pro::facade_builder | ||
::add_convention<MemAt, std::string(int index) const> | ||
::build {}; | ||
|
||
int main() { | ||
std::vector<const char*> v{"hello", "world"}; | ||
pro::proxy<Dictionary> p = &v; | ||
std::cout << p->at(1) << "\n"; // Prints: "world" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from PRO_DEF_WEAK_DISPATCH.md. | ||
|
||
#include <iostream> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include "proxy.h" | ||
|
||
struct NotImplemented { | ||
explicit NotImplemented(auto&&...) { throw std::runtime_error{ "Not implemented!" }; } | ||
|
||
template <class T> | ||
operator T() const noexcept { std::terminate(); } // Or std::unreachable() in C++23 | ||
}; | ||
|
||
PRO_DEF_MEM_DISPATCH(MemAt, at); | ||
PRO_DEF_WEAK_DISPATCH(WeakMemAt, MemAt, NotImplemented); | ||
|
||
struct WeakDictionary : pro::facade_builder | ||
::add_convention<WeakMemAt, std::string(int index) const> | ||
::build {}; | ||
|
||
int main() { | ||
std::vector<const char*> v{"hello", "world"}; | ||
pro::proxy<WeakDictionary> p1 = &v; | ||
std::cout << p1->at(1) << "\n"; // Prints: "world" | ||
pro::proxy<WeakDictionary> p2 = pro::make_proxy<WeakDictionary>(123); | ||
try { | ||
p2->at(1); | ||
} catch (const std::runtime_error& e) { | ||
std::cout << e.what() << "\n"; // Prints: "Not implemented!" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from __msft_lib_proxy.md. | ||
|
||
#include <cstdio> | ||
|
||
#include "proxy.h" | ||
|
||
int main() { | ||
#if defined(__msft_lib_proxy) && __msft_lib_proxy >= 202408L | ||
puts("Compiled with library Proxy 3.0.0 or above."); | ||
#else | ||
puts("Cannot determine the version of library Proxy."); | ||
#endif | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from access_proxy.md. | ||
|
||
#include <iostream> | ||
#include <string> | ||
|
||
#include "proxy.h" | ||
|
||
PRO_DEF_FREE_DISPATCH(FreeToString, std::to_string, ToString); | ||
|
||
struct Stringable : pro::facade_builder | ||
::add_convention<FreeToString, std::string()> | ||
::build {}; | ||
|
||
int main() { | ||
pro::proxy<Stringable> p = pro::make_proxy<Stringable>(123); | ||
|
||
// Invokes with accessibility API | ||
std::cout << ToString(*p) << "\n"; // Prints: "123" | ||
|
||
// How it works behind the scenes | ||
using Convention = std::tuple_element_t<0u, Stringable::convention_types>; | ||
using Accessor = Convention::accessor<Stringable>; | ||
static_assert(std::is_base_of_v<Accessor, std::remove_reference_t<decltype(*p)>>); | ||
Accessor& a = static_cast<Accessor&>(*p); | ||
pro::proxy<Stringable>& p2 = pro::access_proxy<Stringable>(a); | ||
std::cout << std::boolalpha << (&p == &p2) << "\n"; // Prints: "true" because access_proxy converts | ||
// an accessor back to the original proxy | ||
auto result = pro::proxy_invoke<Convention>(p2); | ||
std::cout << result << "\n"; // Prints: "123" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from allocate_proxy.md. | ||
|
||
#include <array> | ||
|
||
#include "proxy.h" | ||
|
||
// By default, the maximum pointer size defined by pro::facade_builder | ||
// is 2 * sizeof(void*). This value can be overridden by `restrict_layout`. | ||
struct Any : pro::facade_builder::build {}; | ||
|
||
int main() { | ||
// sizeof(std::array<int, 100>) is usually greater than 2 * sizeof(void*), | ||
// calling allocate_proxy has no limitation to the size and alignment of the target | ||
using Target = std::array<int, 100>; | ||
pro::proxy<Any> p1 = pro::allocate_proxy<Any, Target>(std::allocator<Target>{}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from basic_facade_builder.md. | ||
|
||
#include <iostream> | ||
|
||
#include "proxy.h" | ||
|
||
template <class... Overloads> | ||
struct MovableCallable : pro::facade_builder | ||
::add_convention<pro::operator_dispatch<"()">, Overloads...> | ||
::build {}; | ||
|
||
template <class... Overloads> | ||
struct CopyableCallable : pro::facade_builder | ||
::support_copy<pro::constraint_level::nontrivial> | ||
::add_facade<MovableCallable<Overloads...>> | ||
::build {}; | ||
|
||
// MyFunction has similar functionality as std::function but supports multiple overloads | ||
// MyMoveOnlyFunction has similar functionality as std::move_only_function but supports multiple overloads | ||
template <class... Overloads> | ||
using MyFunction = pro::proxy<CopyableCallable<Overloads...>>; | ||
template <class... Overloads> | ||
using MyMoveOnlyFunction = pro::proxy<MovableCallable<Overloads...>>; | ||
|
||
int main() { | ||
auto f = [](auto&&... v) { | ||
std::cout << "f() called. Args: "; | ||
((std::cout << v << ":" << typeid(decltype(v)).name() << ", "), ...); | ||
std::cout << "\n"; | ||
}; | ||
MyFunction<void(int)> p0{&f}; | ||
(*p0)(123); // Prints "f() called. Args: 123:i," (assuming GCC) | ||
MyMoveOnlyFunction<void(), void(int), void(double)> p1{&f}; | ||
(*p1)(); // Prints "f() called. Args:" | ||
(*p1)(456); // Prints "f() called. Args: 456:i," | ||
(*p1)(1.2); // Prints "f() called. Args: 1.2:d," | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from add_convention.md. | ||
|
||
#include <iostream> | ||
#include <memory> | ||
#include <string> | ||
|
||
#include "proxy.h" | ||
|
||
PRO_DEF_FREE_DISPATCH(FreeToString, std::to_string, ToString); | ||
|
||
struct BasicStringable : pro::facade_builder | ||
::add_convention<FreeToString, std::string() const> | ||
::build {}; | ||
|
||
struct Stringable : pro::facade_builder | ||
::add_facade<BasicStringable> | ||
::support_copy<pro::constraint_level::nontrivial> | ||
::add_direct_convention<pro::conversion_dispatch<pro::proxy<BasicStringable>>, | ||
pro::proxy<BasicStringable>() &&> | ||
::build {}; | ||
|
||
int main() { | ||
pro::proxy<Stringable> p1 = std::make_shared<int>(123); | ||
pro::proxy<Stringable> p2 = p1; | ||
pro::proxy<BasicStringable> p3 = static_cast<pro::proxy<BasicStringable>>(std::move(p2)); | ||
pro::proxy<BasicStringable> p4 = std::move(p3); | ||
// pro::proxy<BasicStringable> p5 = p4; // Won't compile | ||
std::cout << ToString(*p4) << "\n"; // Prints: "123" | ||
std::cout << std::boolalpha << p3.has_value() << "\n"; // Prints: "false" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from add_facade.md. | ||
|
||
#include <iostream> | ||
#include <unordered_map> | ||
|
||
#include "proxy.h" | ||
|
||
PRO_DEF_MEM_DISPATCH(MemSize, size); | ||
PRO_DEF_MEM_DISPATCH(MemAt, at); | ||
PRO_DEF_MEM_DISPATCH(MemEmplace, emplace); | ||
|
||
struct Copyable : pro::facade_builder | ||
::support_copy<pro::constraint_level::nontrivial> | ||
::build {}; | ||
|
||
struct BasicContainer : pro::facade_builder | ||
::add_convention<MemSize, std::size_t() const noexcept> | ||
::build {}; | ||
|
||
struct StringDictionary : pro::facade_builder | ||
::add_facade<BasicContainer> | ||
::add_facade<Copyable> | ||
::add_convention<MemAt, std::string(std::size_t key) const> | ||
::build {}; | ||
|
||
struct MutableStringDictionary : pro::facade_builder | ||
::add_facade<StringDictionary> | ||
::add_convention<MemEmplace, void(std::size_t key, std::string value)> | ||
::build {}; | ||
|
||
int main() { | ||
pro::proxy<MutableStringDictionary> p1 = | ||
pro::make_proxy<MutableStringDictionary, std::unordered_map<std::size_t, std::string>>(); | ||
std::cout << p1->size() << "\n"; // Prints "0" | ||
try { | ||
std::cout << p1->at(123) << "\n"; // No output because the expression throws | ||
} catch (const std::out_of_range& e) { | ||
std::cerr << e.what() << "\n"; // Prints error message | ||
} | ||
p1->emplace(123, "lalala"); | ||
auto p2 = p1; // Performs a deep copy | ||
p2->emplace(456, "trivial"); | ||
std::cout << p1->size() << "\n"; // Prints "1" | ||
std::cout << p1->at(123) << "\n"; // Prints "lalala" | ||
std::cout << p2->size() << "\n"; // Prints "2" | ||
std::cout << p2->at(123) << "\n"; // Prints "lalala" | ||
std::cout << p2->at(456) << "\n"; // Prints "trivial" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from add_reflection.md. | ||
|
||
#include <iostream> | ||
#include <typeinfo> | ||
|
||
#include "proxy.h" | ||
|
||
class DebugReflection { | ||
public: | ||
template <class P> | ||
constexpr explicit DebugReflection(std::in_place_type_t<P>) | ||
: pointer_type_(typeid(P)), | ||
element_type_(typeid(typename std::pointer_traits<P>::element_type)) {} | ||
|
||
void PrintDebugInfo() const { | ||
std::cout << "Pointer type: " << pointer_type_.name() << "\n"; | ||
std::cout << "Element type: " << element_type_.name() << "\n"; | ||
} | ||
|
||
private: | ||
const std::type_info& pointer_type_; | ||
const std::type_info& element_type_; | ||
}; | ||
|
||
struct TestFacade : pro::facade_builder | ||
::add_reflection<DebugReflection> | ||
::build {}; | ||
|
||
int main() { | ||
pro::proxy<TestFacade> p1 = std::make_shared<int>(123); | ||
pro::proxy_reflect<DebugReflection>(p1).PrintDebugInfo(); // Prints: "Pointer type: St10shared_ptrIiE" | ||
// "Element type: i" (assuming GCC) | ||
|
||
double v = 3.14; | ||
pro::proxy<TestFacade> p2 = &v; | ||
pro::proxy_reflect<DebugReflection>(p2).PrintDebugInfo(); // Prints: "Pointer type: Pd" | ||
// "Element type: d" (assuming GCC) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
// This file contains example code from build.md. | ||
|
||
#include <type_traits> | ||
|
||
#include "proxy.h" | ||
|
||
struct DefaultBase : pro::facade_builder | ||
::build {}; | ||
|
||
struct CopyableBase : pro::facade_builder | ||
::support_copy<pro::constraint_level::nontrivial> | ||
::build {}; | ||
|
||
struct TrivialBase : pro::facade_builder | ||
::support_copy<pro::constraint_level::trivial> | ||
::support_relocation<pro::constraint_level::trivial> | ||
::support_destruction<pro::constraint_level::trivial> | ||
::restrict_layout<sizeof(void*)> | ||
::build {}; | ||
|
||
int main() { | ||
static_assert(!std::is_copy_constructible_v<pro::proxy<DefaultBase>>); | ||
static_assert(std::is_nothrow_move_constructible_v<pro::proxy<DefaultBase>>); | ||
static_assert(std::is_nothrow_destructible_v<pro::proxy<DefaultBase>>); | ||
|
||
static_assert(std::is_copy_constructible_v<pro::proxy<CopyableBase>>); | ||
static_assert(std::is_nothrow_move_constructible_v<pro::proxy<CopyableBase>>); | ||
static_assert(std::is_nothrow_destructible_v<pro::proxy<CopyableBase>>); | ||
|
||
static_assert(std::is_trivially_copy_constructible_v<pro::proxy<TrivialBase>>); | ||
static_assert(std::is_trivially_move_constructible_v<pro::proxy<TrivialBase>>); | ||
static_assert(std::is_trivially_destructible_v<pro::proxy<TrivialBase>>); | ||
} |
Oops, something went wrong.