Skip to content
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

std::filesystem::path support #27

Merged
merged 1 commit into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/alpaca/alpaca.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <alpaca/detail/types/array.h>
#include <alpaca/detail/types/deque.h>
#include <alpaca/detail/types/duration.h>
#include <alpaca/detail/types/filesystem_path.h>
#include <alpaca/detail/types/list.h>
#include <alpaca/detail/types/map.h>
#include <alpaca/detail/types/optional.h>
Expand Down
5 changes: 3 additions & 2 deletions include/alpaca/detail/field_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ enum class field_type : uint8_t {
struct_,
chrono_duration,
list,
deque
deque,
filesystem_path
};

template <field_type value> constexpr uint8_t to_byte() {
Expand All @@ -43,4 +44,4 @@ template <field_type value> constexpr uint8_t to_byte() {

} // namespace detail

} // namespace alpaca
} // namespace alpaca
2 changes: 1 addition & 1 deletion include/alpaca/detail/to_bytes.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@ to_bytes(T &bytes, std::size_t &byte_index, const U &value) {

} // namespace detail

} // namespace alpaca
} // namespace alpaca
15 changes: 14 additions & 1 deletion include/alpaca/detail/type_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#include <array>
#endif

#ifndef ALPACA_EXCLUDE_SUPPORT_STD_FILESYSTEM_PATH
#include <filesystem>
#endif

#ifndef ALPACA_EXCLUDE_SUPPORT_STD_MAP
#include <map>
#endif
Expand Down Expand Up @@ -169,6 +173,15 @@ typename std::enable_if<is_array_type<T>::value, void>::type type_info(
std::unordered_map<std::string_view, std::size_t> &struct_visitor_map);
#endif

#ifndef ALPACA_EXCLUDE_SUPPORT_STD_FILESYSTEM_PATH
// filesystem::path
template <typename T>
typename std::enable_if<std::is_same<T, std::filesystem::path>::value, void>::type
type_info(
std::vector<uint8_t> &typeids,
std::unordered_map<std::string_view, std::size_t> &struct_visitor_map);
#endif

#ifndef ALPACA_EXCLUDE_SUPPORT_STD_MAP
// map
template <typename T>
Expand Down Expand Up @@ -270,4 +283,4 @@ type_info(

} // namespace detail

} // namespace alpaca
} // namespace alpaca
79 changes: 79 additions & 0 deletions include/alpaca/detail/types/filesystem_path.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#pragma once
#ifndef ALPACA_EXCLUDE_SUPPORT_STD_FILESYSTEM_PATH
#include <alpaca/detail/from_bytes.h>
#include <alpaca/detail/to_bytes.h>
#include <alpaca/detail/type_info.h>
#include <filesystem>
#include <system_error>
#include <vector>

namespace alpaca {

namespace detail {

template <typename T>
typename std::enable_if<std::is_same<T, std::filesystem::path>::value,
void>::type
type_info(std::vector<uint8_t> &typeids,
std::unordered_map<std::string_view, std::size_t> &) {
typeids.push_back(to_byte<field_type::filesystem_path>());
}

template <options O, typename T, typename Container>
void to_bytes_router(const T &input, Container &bytes, std::size_t &byte_index);

template <options O, typename Container>
void to_bytes(Container &bytes, std::size_t &byte_index,
const std::filesystem::path &input) {
// save string length
to_bytes_router<O>(input.native().size(), bytes, byte_index);

for (const auto &c : input.native()) {
to_bytes<O>(bytes, byte_index, c);
}
}

template <options O, typename Container>
bool from_bytes(std::filesystem::path &value, Container &bytes,
std::size_t &current_index, std::size_t &end_index,
std::error_code &error_code) {

if (current_index >= end_index) {
// end of input
// return true for forward compatibility
return true;
}

// current byte is the length of the string
std::size_t size = 0;
detail::from_bytes<O, std::size_t>(size, bytes, current_index, end_index,
error_code);

if (size > end_index - current_index) {
// size is greater than the number of bytes remaining
error_code = std::make_error_code(std::errc::value_too_large);

// stop here
return false;
}

// read `size` bytes and save to value
std::filesystem::path::string_type buff;
using CharType = std::filesystem::path::value_type;

buff.reserve(size * sizeof(CharType));

for (std::size_t i = 0; i < size; ++i) {
CharType character{};
from_bytes<O>(character, bytes, current_index, end_index, error_code);
buff += character;
}

value = std::move(buff);
return true;
}

} // namespace detail

} // namespace alpaca
#endif
Loading