Skip to content

Commit

Permalink
[core.memory] view_bytes now works much better and is easier to maint…
Browse files Browse the repository at this point in the history
…ain. also in the case image_info fails to parse image data properly, return a much more detailled error message
  • Loading branch information
harrand committed Nov 8, 2024
1 parent bcda695 commit 48ab587
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 24 deletions.
54 changes: 31 additions & 23 deletions include/tz/core/memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,38 @@

namespace tz
{
template<typename T> requires(std::is_standard_layout_v<T>)
std::span<const std::byte> view_bytes(const T& t)
template<typename T>
constexpr auto view_bytes(T&& t) -> std::conditional_t<std::is_const_v<T>, std::span<const std::byte>, std::span<std::byte>>
{
return std::as_bytes(std::span<const T>(&t, 1));
}

template<typename T> requires(std::is_standard_layout_v<T>)
std::span<std::byte> view_bytes(T& t)
{
return std::as_writable_bytes(std::span<T>(&t, 1));
}

template<std::ranges::contiguous_range R> requires(std::is_const_v<std::ranges::range_value_t<R>>)
std::span<const std::byte> view_bytes(R&& range)
{
using T = std::ranges::range_value_t<R>;
return std::as_bytes(std::span<const T>(std::ranges::begin(range), std::ranges::end(range)));
}

template<std::ranges::contiguous_range R>
std::span<std::byte> view_bytes(R&& range)
{
using T = std::ranges::range_value_t<R>;
return std::as_writable_bytes(std::span<T>(std::ranges::begin(range), std::ranges::end(range)));
if constexpr(requires{std::ranges::contiguous_range<T>;})
{
// we are a range
using V = std::ranges::range_value_t<T>;
std::span<V> range{std::begin(t), std::end(t)};
if constexpr(std::is_const_v<V>)
{
return std::as_bytes(range);
}
else
{
return std::as_writable_bytes(range);
}
}
else
{
// we are not a range
static_assert(std::is_standard_layout_v<T>, "view_bytes must be provided a contiguous range or a standard-layout-type. You have provided neither.");
// we are a scalar-y value
std::span<T, 1> span{&t};
if constexpr(std::is_const_v<T>)
{
return std::as_bytes(span);
}
else
{
return std::as_writable_bytes(span);
}
}
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/tz/io/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#define STBI_FAILURE_USERMSG
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <vector>
#include <algorithm>

namespace tz::io
{
Expand All @@ -12,7 +14,11 @@ namespace tz::io
int ok = stbi_info_from_memory(reinterpret_cast<const stbi_uc*>(img_file_data.data()), img_file_data.size_bytes(), &w, &h, &channels);
if(ok != 1)
{
UNERR(tz::error_code::precondition_failure, "bad image file data: {}", stbi_failure_reason());
std::vector<char> initial_snippet;
initial_snippet.resize(std::min(static_cast<std::size_t>(20), img_file_data.size_bytes()));
std::transform(img_file_data.begin(), img_file_data.begin() + initial_snippet.size(), initial_snippet.begin(), [](std::byte ch)->char{return static_cast<char>(ch);});

UNERR(tz::error_code::precondition_failure, "bad image file data. reason: {}\ndata snippet ({}): \"{}\"", stbi_failure_reason(), initial_snippet.size(), reinterpret_cast<char*>(initial_snippet.data()));
}

return image_header
Expand Down

0 comments on commit 48ab587

Please sign in to comment.