-
Notifications
You must be signed in to change notification settings - Fork 289
Enable string-views for use with Tracelogging #589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ | |
| #include <string> | ||
| #include <vector> | ||
| #include <utility> | ||
| #include <TraceLoggingProvider.h> | ||
| #if (__WI_LIBCPP_STD_VER >= 17) && WI_HAS_INCLUDE(<string_view>, 1) // Assume present if C++17 | ||
| #include <string_view> | ||
| #endif | ||
|
|
@@ -266,6 +267,76 @@ struct std::formatter<wil::basic_zstring_view<TChar>, TChar> : std::formatter<st | |
| }; | ||
| #endif | ||
|
|
||
| #if __cpp_lib_string_view >= 201606L | ||
|
|
||
| template <typename TContainer> | ||
| struct _tlgWrapBufferStlContainer | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| { | ||
| static const unsigned DataDescCount = 2; | ||
|
|
||
| TContainer const& view; | ||
|
|
||
| __forceinline explicit _tlgWrapBufferStlContainer(_In_ TContainer const& ref) : view(ref) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does this need our special __forceinline keyword? can we just use the standard 'inline' keyword?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as this is a template parameter, can we use a 'Universal Reference' with std::forward? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that achieves anything here. Universal reference is so that you can accept both const and non-const references, or so you can accept both non-const-rvalue and non-const-lvalue references. We only need to be able to accept a const reference, so no fancy universal reference is needed.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's because moves don't buy us anything for these templated types vs. making copies? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are no copies. It's a const ref all the way down.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oops. yep. sorry, missed that!
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Jon - feel free to close this. I can't seem to resolve/close it myself :( |
||
| { | ||
| } | ||
|
|
||
| __forceinline void* Fill(_Out_writes_(DataDescCount) EVENT_DATA_DESCRIPTOR* pDesc) const | ||
| { | ||
| EventDataDescCreate(&pDesc[0], &pDesc[1].Size, 2); | ||
| EventDataDescCreate(&pDesc[1], view.data(), static_cast<UINT16>(view.size() * sizeof(*view.data()))); | ||
| return pDesc; | ||
| } | ||
| }; | ||
|
|
||
| template <typename TChar> | ||
| struct _tlgTypeMapStlString | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should not use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably have a specialization for |
||
| { | ||
| typedef UINT8 _tlgTypeType0; | ||
| typedef UINT16 _tlgTypeType1; | ||
| static bool const _tlgIsSimple = false; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can these be constexpr? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There isn't really any significant difference between class scope
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure. I tend to make everything constexpr that can be supported, as I don't assume what the compiler can optimize / change where it puts such things - so I make it the rule, not the exception :) it's clearly not a bit deal to go either way to me. |
||
| static TlgIn_t const _tlgViewIn = wistd::is_same_v<TChar, char> ? TlgInCOUNTEDANSISTRING : TlgInCOUNTEDSTRING; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably be based on |
||
| static _tlgTypeType0 const _tlgType0 = _tlgViewIn | 0x0000; | ||
| static _tlgTypeType1 const _tlgType1 = _tlgViewIn | 0x8080; | ||
| }; | ||
|
|
||
| template <typename TChar, typename TTraits> | ||
| struct _tlgTypeMapBase<std::basic_string_view<TChar, TTraits>> : _tlgTypeMapStlString<TChar> | ||
| { | ||
| }; | ||
|
|
||
| template <typename TChar, typename TTraits> | ||
| TLG_INLINE auto _tlg_CALL _tlgWrapAuto(std::basic_string_view<TChar, TTraits> const& value) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't use
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why would we need a calling convention for this template function? is it passed as a function pointer somewhere? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In practice, it's probably not particularly significant. However, it is possible for two LIBs to use different default calling conventions and both include the header. In that case, the linker will see two distinct inline functions, and that can be confusing or sub-optimal. I just find it to be best practice to put a calling convention on any non-member function declaration in a header.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok. I don't think we put calling conventions on standalone functions anywhere else in wil :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't need
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we probably don't need TLG_INLINE either. |
||
| { | ||
| return _tlgWrapBufferStlContainer<std::basic_string_view<TChar, TTraits>>(value); | ||
| } | ||
|
|
||
| template <typename TChar, typename TTraits> | ||
| struct _tlgTypeMapBase<std::basic_string<TChar, TTraits>> : _tlgTypeMapStlString<TChar> | ||
| { | ||
| }; | ||
|
|
||
| template <typename TChar, typename TTraits> | ||
| TLG_INLINE auto _tlg_CALL _tlgWrapAuto(std::basic_string<TChar, TTraits> const& value) | ||
| { | ||
| return _tlgWrapBufferStlContainer<std::basic_string<TChar, TTraits>>(value); | ||
| } | ||
|
|
||
| template <typename TChar> | ||
| struct _tlgTypeMapBase<wil::basic_zstring_view<TChar>> : _tlgTypeMapStlString<TChar> | ||
| { | ||
| }; | ||
|
|
||
| template <typename TChar> | ||
| TLG_INLINE auto _tlg_CALL _tlgWrapAuto(wil::basic_zstring_view<TChar> const& value) | ||
| { | ||
| return _tlgWrapBufferStlContainer<wil::basic_zstring_view<TChar>>(value); | ||
| } | ||
|
|
||
| #define TraceLoggingStringView(pValue, ...) _tlgArgAuto(static_cast<std::string_view>(pValue), __VA_ARGS__) | ||
| #define TraceLoggingWideStringView(pValue, ...) _tlgArgAuto(static_cast<std::wstring_view>(pValue), __VA_ARGS__) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The parameter to this macro should not be a pointer, so probably shouldn't be named |
||
|
|
||
| #endif // __cpp_lib_string_view >= 201606L | ||
|
|
||
| #endif // WIL_ENABLE_EXCEPTIONS | ||
|
|
||
| #endif // __WIL_STL_INCLUDED | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -40,7 +40,7 @@ if not exist %BUILD_DIR% ( goto :eof ) | |||||
| :: MSVC does not currently ship a version of the x64 ASan DLL that can be run on an arm64 host. MSVC _does_ ship a lib | ||||||
| :: so we _can_ build the ASan tests, which is at least something. For now we're going to handle this limitation here and | ||||||
| :: avoid running the ASan test in this specific scenario | ||||||
| set RUN_ASAN_TEST=1 | ||||||
| if not %RUN_ASAN_TEST%=='' set RUN_ASAN_TEST=1 | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume your intent is to initialize if not set, in which case the
Suggested change
|
||||||
| if %PROCESSOR_ARCHITECTURE%==ARM64 ( | ||||||
| if %2==x64 set RUN_ASAN_TEST=0 | ||||||
| ) | ||||||
|
|
@@ -69,11 +69,15 @@ if %ERRORLEVEL% NEQ 0 ( goto :execute_tests_done ) | |||||
|
|
||||||
| :execute_tests_done | ||||||
| set EXIT_CODE=%ERRORLEVEL% | ||||||
| if %EXIT_CODE% NEQ 0 ( | ||||||
| echo Tests failed in %BUILD_DIR% with exit code %EXIT_CODE% | ||||||
| goto :eof | ||||||
| ) | ||||||
| popd | ||||||
| exit /B %EXIT_CODE% | ||||||
|
|
||||||
| :execute_test | ||||||
| if not exist tests\%1\%2 ( goto :eof ) | ||||||
| echo Running %1 tests... | ||||||
| echo Running tests\%1\%2 %TEST_ARGS% | ||||||
| tests\%1\%2 %TEST_ARGS% | ||||||
| goto :eof | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically this is illegally reaching into internal implementation details of TraceLoggingProvider.h.
Probably the right thing to do is: