Skip to content
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/fast_io_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@

#include "fast_io_core_impl/integers/chrono.h"
#include "fast_io_core_impl/iso/isos.h"
#include "fast_io_core_impl/linux_statx_definitions/impl.h"
#include "fast_io_core_impl/enums/impl.h"

#ifndef FAST_IO_DISABLE_CODECVT
Expand Down
8 changes: 8 additions & 0 deletions include/fast_io_core_impl/linux_statx_definitions/impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once
/*
https://www.man7.org/linux//man-pages/man2/statx.2.html
*/
#include "linux_statx_timestamp.h"
#include "linux_statx.h"
#include "linux_statx_flags.h"
#include "linux_statx_mask.h"
59 changes: 59 additions & 0 deletions include/fast_io_core_impl/linux_statx_definitions/linux_statx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#pragma once

namespace fast_io
{

struct linux_statxbuf
{
::std::uint_least32_t stx_mask; /* Mask of bits indicating
filled fields */
::std::uint_least32_t stx_blksize; /* Block size for filesystem I/O */
::std::uint_least64_t stx_attributes; /* Extra file attribute indicators */
::std::uint_least32_t stx_nlink; /* Number of hard links */
::std::uint_least32_t stx_uid; /* User ID of owner */
::std::uint_least32_t stx_gid; /* Group ID of owner */
::std::uint_least16_t stx_mode; /* File type and mode */
::std::uint_least64_t stx_ino; /* Inode number */
::std::uint_least64_t stx_size; /* Total size in bytes */
::std::uint_least64_t stx_blocks; /* Number of 512B blocks allocated */
::std::uint_least64_t stx_attributes_mask;
/* Mask to show what's supported
in stx_attributes */

/* The following fields are file timestamps */
::fast_io::linux_statx_timestamp stx_atime; /* Last access */
::fast_io::linux_statx_timestamp stx_btime; /* Creation */
::fast_io::linux_statx_timestamp stx_ctime; /* Last status change */
::fast_io::linux_statx_timestamp stx_mtime; /* Last modification */

/* If this file represents a device, then the next two
fields contain the ID of the device */
::std::uint_least32_t stx_rdev_major; /* Major ID */
::std::uint_least32_t stx_rdev_minor; /* Minor ID */

/* The next two fields contain the ID of the device
containing the filesystem where the file resides */
::std::uint_least32_t stx_dev_major; /* Major ID */
::std::uint_least32_t stx_dev_minor; /* Minor ID */

::std::uint_least64_t stx_mnt_id; /* Mount ID */

/* Direct I/O alignment restrictions */
::std::uint_least32_t stx_dio_mem_align;
::std::uint_least32_t stx_dio_offset_align;

::std::uint_least64_t stx_subvol; /* Subvolume identifier */

/* Direct I/O atomic write limits */
::std::uint_least32_t stx_atomic_write_unit_min;
::std::uint_least32_t stx_atomic_write_unit_max;
::std::uint_least32_t stx_atomic_write_segments_max;

/* File offset alignment for direct I/O reads */
::std::uint_least32_t stx_dio_read_offset_align;

/* Direct I/O atomic write max opt limit */
::std::uint_least32_t stx_atomic_write_unit_max_opt;
};

} // namespace fast_io
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

namespace fast_io
{

enum class linux_statx_flags : ::std::uint_least32_t
{
at_empty_path = 0x1000, // AT_EMPTY_PATH
at_no_automount = 0x800, // AT_NO_AUTOMOUNT
at_symlink_nofollow = 0x100, // AT_SYMLINK_NOFOLLOW

// statx-specific sync flags
at_statx_sync_as_stat = 0x0000, // AT_STATX_SYNC_AS_STAT
at_statx_force_sync = 0x2000, // AT_STATX_FORCE_SYNC
at_statx_dont_sync = 0x4000 // AT_STATX_DONT_SYNC
};

inline constexpr ::fast_io::linux_statx_flags operator&(::fast_io::linux_statx_flags x, ::fast_io::linux_statx_flags y) noexcept
{
using utype = typename ::std::underlying_type<::fast_io::linux_statx_flags>::type;
return static_cast<::fast_io::linux_statx_flags>(static_cast<utype>(x) & static_cast<utype>(y));
}

inline constexpr ::fast_io::linux_statx_flags operator|(::fast_io::linux_statx_flags x, ::fast_io::linux_statx_flags y) noexcept
{
using utype = typename ::std::underlying_type<::fast_io::linux_statx_flags>::type;
return static_cast<::fast_io::linux_statx_flags>(static_cast<utype>(x) | static_cast<utype>(y));
}

inline constexpr ::fast_io::linux_statx_flags operator^(::fast_io::linux_statx_flags x, ::fast_io::linux_statx_flags y) noexcept
{
using utype = typename ::std::underlying_type<::fast_io::linux_statx_flags>::type;
return static_cast<::fast_io::linux_statx_flags>(static_cast<utype>(x) ^ static_cast<utype>(y));
}

inline constexpr ::fast_io::linux_statx_flags operator~(::fast_io::linux_statx_flags x) noexcept
{
using utype = typename ::std::underlying_type<::fast_io::linux_statx_flags>::type;
return static_cast<::fast_io::linux_statx_flags>(~static_cast<utype>(x));
}

inline constexpr ::fast_io::linux_statx_flags &operator&=(::fast_io::linux_statx_flags &x, ::fast_io::linux_statx_flags y) noexcept
{
return x = x & y;
}

inline constexpr ::fast_io::linux_statx_flags &operator|=(::fast_io::linux_statx_flags &x, ::fast_io::linux_statx_flags y) noexcept
{
return x = x | y;
}

inline constexpr ::fast_io::linux_statx_flags &operator^=(::fast_io::linux_statx_flags &x, ::fast_io::linux_statx_flags y) noexcept
{
return x = x ^ y;
}

} // namespace fast_io
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once

namespace fast_io
{

enum class linux_statx_mask : ::std::uint_least32_t
{
statx_type = 0x00000001, // Request file type information (stx_mode & S_IFMT)
statx_mode = 0x00000002, // Request file mode/permission bits (stx_mode & ~S_IFMT)
statx_nlink = 0x00000004, // Request number of hard links
statx_uid = 0x00000008, // Request owning user ID
statx_gid = 0x00000010, // Request owning group ID
statx_atime = 0x00000020, // Request last access timestamp
statx_mtime = 0x00000040, // Request last modification timestamp
statx_ctime = 0x00000080, // Request inode status change timestamp
statx_ino = 0x00000100, // Request inode number
statx_size = 0x00000200, // Request file size in bytes
statx_blocks = 0x00000400, // Request number of 512-byte blocks allocated
statx_basic_stats = 0x000007ff, // Request all basic attributes (type through blocks)
statx_btime = 0x00000800, // Request file creation (birth) timestamp
statx_mnt_id = 0x00001000, // Request mount ID of the filesystem
statx_dioalign = 0x00002000, // Request direct I/O alignment constraints
statx_mnt_id_unique = 0x00004000, // Request unique mount ID (stronger than stx_mnt_id)
statx_subvol = 0x00008000, // Request subvolume identifier (e.g., btrfs)
statx_write_atomic = 0x00010000, // Request atomic write capability information
statx_dio_read_align = 0x00020000 // Request direct I/O read offset alignment
};

inline constexpr ::fast_io::linux_statx_mask operator&(::fast_io::linux_statx_mask x, ::fast_io::linux_statx_mask y) noexcept
{
using utype = typename ::std::underlying_type<::fast_io::linux_statx_mask>::type;
return static_cast<::fast_io::linux_statx_mask>(static_cast<utype>(x) & static_cast<utype>(y));
}

inline constexpr ::fast_io::linux_statx_mask operator|(::fast_io::linux_statx_mask x, ::fast_io::linux_statx_mask y) noexcept
{
using utype = typename ::std::underlying_type<::fast_io::linux_statx_mask>::type;
return static_cast<::fast_io::linux_statx_mask>(static_cast<utype>(x) | static_cast<utype>(y));
}

inline constexpr ::fast_io::linux_statx_mask operator^(::fast_io::linux_statx_mask x, ::fast_io::linux_statx_mask y) noexcept
{
using utype = typename ::std::underlying_type<::fast_io::linux_statx_mask>::type;
return static_cast<::fast_io::linux_statx_mask>(static_cast<utype>(x) ^ static_cast<utype>(y));
}

inline constexpr ::fast_io::linux_statx_mask operator~(::fast_io::linux_statx_mask x) noexcept
{
using utype = typename ::std::underlying_type<::fast_io::linux_statx_mask>::type;
return static_cast<::fast_io::linux_statx_mask>(~static_cast<utype>(x));
}

inline constexpr ::fast_io::linux_statx_mask &operator&=(::fast_io::linux_statx_mask &x, ::fast_io::linux_statx_mask y) noexcept
{
return x = x & y;
}

inline constexpr ::fast_io::linux_statx_mask &operator|=(::fast_io::linux_statx_mask &x, ::fast_io::linux_statx_mask y) noexcept
{
return x = x | y;
}

inline constexpr ::fast_io::linux_statx_mask &operator^=(::fast_io::linux_statx_mask &x, ::fast_io::linux_statx_mask y) noexcept
{
return x = x ^ y;
}

} // namespace fast_io
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

namespace fast_io
{

struct linux_statx_timestamp
{
::std::int_least64_t tv_sec; // Seconds since the Epoch (UNIX time)
::std::uint_least32_t tv_nsec; // Nanoseconds since tv_sec
};

#if 0
template<typename T>
requires requires(T t)
{
T::rep;
T::period;
t.count();
}
inline constexpr linux_statx_timestamp linux_statx_timestamp_from_duration_std(T dur) noexcept
{
using rep = typename T::rep;
using period = typename T::period;

// total count
rep c = dur.count();

// Convert to seconds and nanoseconds WITHOUT overflow
// tv_sec = c * period::num / period::den
// tv_nsec = remainder * 1'000'000'000 / period::den

// Step 1: compute whole seconds
// We do integer division first to avoid overflow.
constexpr std::int_least64_t num = period::num;
constexpr std::int_least64_t den = period::den;

// seconds = floor(c * num / den)
// but compute as (c / den) * num + (c % den) * num / den
std::int_least64_t sec = (static_cast<std::int_least64_t>(c) / den) * num;

// remainder part
std::int_least64_t rem = static_cast<std::int_least64_t>(c) % den;

sec += (rem * num) / den;

// Step 2: compute nanoseconds
// nsec = ((rem * num) % den) * 1e9 / den
std::int_least64_t rem2 = (rem * num) % den;

std::uint_least32_t nsec =
static_cast<std::uint_least32_t>((rem2 * 1000000000LL) / den);

return linux_statx_timestamp{sec, nsec};
}
#endif

} // namespace fast_io
24 changes: 23 additions & 1 deletion include/fast_io_dsal/impl/deque.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ inline constexpr ::std::ptrdiff_t deque_iter_difference_common(::fast_io::contai
template <typename T>
inline constexpr ::std::size_t deque_iter_difference_unsigned_common(::fast_io::containers::details::deque_control_block<T> const &a, ::fast_io::containers::details::deque_control_block<T> const &b) noexcept
{
::std::size_t controllerdiff{a.controller_ptr - b.controller_ptr};
::std::size_t controllerdiff{static_cast<::std::size_t>(a.controller_ptr - b.controller_ptr)};
constexpr ::std::size_t blocksizedf{::fast_io::containers::details::deque_block_size<sizeof(T)>};
return controllerdiff * blocksizedf + static_cast<::std::size_t>((a.curr_ptr - a.begin_ptr) + (b.begin_ptr - b.curr_ptr));
}
Expand Down Expand Up @@ -2236,6 +2236,28 @@ inline constexpr auto operator<=>(deque<T, allocator1> const &lhs, deque<T, allo

#endif

template <typename T, typename Alloc, typename U = T>
constexpr typename ::fast_io::containers::deque<T, Alloc>::size_type
erase(::fast_io::containers::deque<T, Alloc> &c, U const &value)
{
auto ed{c.end()};
auto it = ::std::remove(c.begin(), ed, value);
auto r = ::fast_io::containers::details::deque_iter_difference_unsigned_common(ed.itercontent, it.itercontent);
c.erase(it, ed);
return r;
}

template <typename T, typename Alloc, typename Pred>
constexpr typename ::fast_io::containers::deque<T, Alloc>::size_type
erase_if(::fast_io::containers::deque<T, Alloc> &c, Pred pred)
{
auto ed{c.end()};
auto it = ::std::remove_if(c.begin(), ed, pred);
auto r = ::fast_io::containers::details::deque_iter_difference_unsigned_common(ed.itercontent, it.itercontent);
c.erase(it, ed);
return r;
}

} // namespace containers

namespace freestanding
Expand Down
Loading