zeek/auxil/out_ptr/examples/source/customization.traits.handle.cpp
Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

89 lines
2.6 KiB
C++

// Copyright ⓒ 2018-2021 ThePhD.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// See https://github.com/ThePhD/out_ptr/blob/master/docs/out_ptr.adoc for documentation.
#include <phd/handle.hpp>
#include <ficapi/ficapi.hpp>
#include <ztd/out_ptr.hpp>
#include <assert.hpp>
#include <type_traits>
// A template that always evaluates to false anyhow
template <std::size_t I>
struct always_false_index : std::integral_constant<bool, I == 1 && I == 0> {};
namespace ztd { namespace out_ptr {
// this is the simple customization point
// you don't get access to the underlying storage,
// but you can utilize the ::pointer typedef to
// cutsomize the state utilized
template <typename T, typename D, typename Pointer>
class inout_ptr_traits<ztd::handle<T, D>, Pointer> {
private:
using Smart = ztd::handle<T, D>;
using source_pointer = pointer_of_or_t<ztd::handle<T, D>, Pointer>;
struct optimized_pointer_state {
Pointer* target;
optimized_pointer_state(Pointer* target_ptr) noexcept
: target(target_ptr) {
}
optimized_pointer_state(optimized_pointer_state&& right) noexcept
: target(right.target) {
}
optimized_pointer_state& operator=(optimized_pointer_state&& right) noexcept {
target = std::move(right.target);
}
explicit operator bool() const noexcept {
return target != nullptr;
}
};
public:
using pointer = optimized_pointer_state;
static pointer construct(Smart& s) {
return pointer(reinterpret_cast<Pointer*>(std::addressof(s.get())));
}
static Pointer* get(Smart&, pointer& state) noexcept {
return state.target;
}
static void reset(Smart&, pointer&) noexcept {
// value already written directly into the pointer
}
};
}} // namespace ztd::out_ptr
int main() {
ztd::handle<int*, ficapi::int_deleter> p(nullptr);
ficapi_re_create(ztd::out_ptr::inout_ptr<void*>(p), ficapi_type::ficapi_type_int);
int* rawp = static_cast<int*>(p.get());
OUT_PTR_C_ASSERT(rawp != nullptr);
OUT_PTR_C_ASSERT(*rawp == ficapi_get_dynamic_data());
}