Skip to content

Commit

Permalink
std::filesystem::path support
Browse files Browse the repository at this point in the history
  • Loading branch information
f-michaut committed Dec 10, 2023
1 parent 3654776 commit 0626cf9
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 4 deletions.
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

0 comments on commit 0626cf9

Please sign in to comment.