OGLplus  (0.59.0) a C++ wrapper for rendering APIs

eagine/c_api_wrap.cpp

Copyright Matus Chochlik. Distributed under the Boost Software License, Version 1.0. See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt

#include <iostream>
#if EAGINE_POSIX
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#define EXAMPLE_API_STATIC_FUNC(NAME) &::NAME
#else
#define EXAMPLE_API_STATIC_FUNC(NAME) nullptr
#endif
namespace eagine {
//------------------------------------------------------------------------------
struct example_sets_errno {};
//------------------------------------------------------------------------------
struct example_api_traits : default_c_api_traits {};
//------------------------------------------------------------------------------
struct example_file_api {
using this_api = example_file_api;
using api_traits = example_api_traits;
template <typename Tag = example_sets_errno>
using derived_func = derived_c_api_function<this_api, api_traits, Tag>;
api_traits,
example_sets_errno,
int(int[2]),
EXAMPLE_API_STATIC_FUNC(pipe),
EAGINE_POSIX,
true>
make_pipe;
struct : derived_func<> {
using base = derived_func<>;
using base::base;
explicit constexpr operator bool() const noexcept {
return EAGINE_POSIX != 0;
}
auto operator()(const char* path, int flags) noexcept -> ssize_t {
EAGINE_MAYBE_UNUSED(path);
EAGINE_MAYBE_UNUSED(flags);
#if EAGINE_POSIX
return ::open(path, flags); // NOLINT(hicpp-vararg)
#else
return -1;
#endif
}
} open_file;
api_traits,
example_sets_errno,
ssize_t(int, void*, size_t),
EXAMPLE_API_STATIC_FUNC(read),
EAGINE_POSIX,
true>
read_file;
struct : derived_func<> {
using base = derived_func<>;
using base::api;
using base::base;
explicit constexpr operator bool() const noexcept {
return bool(api().read_file);
}
auto operator()(int fd, memory::block blk) noexcept -> ssize_t {
return api().read_file(
fd,
static_cast<void*>(blk.data()),
static_cast<size_t>(blk.size()));
}
} read_block;
api_traits,
example_sets_errno,
ssize_t(int, const void*, size_t),
EXAMPLE_API_STATIC_FUNC(write),
EAGINE_POSIX,
true>
write_file;
struct : derived_func<> {
using base = derived_func<>;
using base::api;
using base::base;
explicit constexpr operator bool() const noexcept {
return bool(api().write_file);
}
auto operator()(int fd, memory::const_block blk) noexcept -> ssize_t {
return api().write_file(
fd,
static_cast<const void*>(blk.data()),
static_cast<size_t>(blk.size()));
}
} write_block;
struct : derived_func<> {
using base = derived_func<>;
using base::api;
using base::base;
explicit constexpr operator bool() const noexcept {
return bool(api().write_file);
}
auto operator()(int fd, string_view str) noexcept -> ssize_t {
return api().write_file(
fd,
static_cast<const void*>(str.data()),
static_cast<size_t>(str.size()));
}
} write_string;
api_traits,
example_sets_errno,
int(int),
EXAMPLE_API_STATIC_FUNC(close),
EAGINE_POSIX,
true>
close_file;
example_file_api(api_traits& traits)
: make_pipe{"pipe", traits, *this}
, open_file{"open", traits, *this}
, read_file{"read", traits, *this}
, read_block("read", traits, *this)
, write_file{"write", traits, *this}
, write_block("write", traits, *this)
, write_string("write", traits, *this)
, close_file{"close", traits, *this} {}
};
//------------------------------------------------------------------------------
} // namespace eagine
auto main(int, const char** argv) -> int {
using namespace eagine;
example_api_traits traits;
example_file_api api(traits);
if(api.make_pipe && api.write_block && api.read_block && api.close_file) {
int pfd[2] = {-1, -1};
api.make_pipe(pfd);
auto make_getbyte = [&api](int fd) {
return [&api, fd]() -> optionally_valid<byte> {
byte b{};
if(api.read_block(fd, cover_one(b)) > 0) {
return {b, true};
}
api.close_file(fd);
return {};
};
};
auto putchar = [](char c) {
std::cout << c;
return true;
};
if(api.open_file) {
int fd = api.open_file(argv[0], 0);
if(fd >= 0) {
auto getbyte = make_getbyte(fd);
while(auto optb = getbyte()) {
api.write_block(pfd[1], view_one(extract(optb)));
}
}
} else {
std::cerr << "open function is not available" << std::endl;
}
api.write_string(pfd[1], "some test string");
api.write_string(pfd[1], "one other string");
api.close_file(pfd[1]);
{construct_from, make_getbyte(pfd[0])}, {construct_from, putchar});
} else {
std::cerr << "required API is not available" << std::endl;
}
return 0;
}
basic_string_span< const char > string_view
Alias for const string views.
Definition: string_span.hpp:116
std::conditional_t< IsAvailable, std::conditional_t< IsStatic, static_c_api_function< ApiTraits, Tag, Signature, function >, dynamic_c_api_function< ApiTraits, Tag, Signature > >, unimplemented_c_api_function< ApiTraits, Tag, Signature > > opt_c_api_function
Template alias used for switching between static and dynamic function.
Definition: c_api_wrap.hpp:1096
Common code is placed in this namespace.
Definition: eagine.hpp:21
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
basic_block< true > const_block
Alias for const byte memory span.
Definition: block.hpp:32
Primary template for conditionally valid values.
Definition: decl.hpp:49
basic_block< false > block
Alias for non-const byte memory span.
Definition: block.hpp:27
constexpr const construct_from_t construct_from
The construct-from tag-dispatch constant.
Definition: selector.hpp:47
static void apply(byte_getter get_byte, char_putter put_char)
Uses get_byte to read input bytes, encodes them and calls put_char.

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).