Skip to content

Commit

Permalink
added oriented direction and axis
Browse files Browse the repository at this point in the history
  • Loading branch information
ABouttefeux committed Dec 10, 2023
1 parent 6232ae2 commit ccd78c7
Show file tree
Hide file tree
Showing 12 changed files with 1,647 additions and 966 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
- [`LatticeIterator`] and [`LatticeParIter`] and be easily converted into each other.
- implemented [`LatticeElementToIndex`] for [`DirectionEnum`].
- added [`LatticeCyclic::par_iter_links`] and [`LatticeCyclic::par_iter_points`] to get parallel iterator on the links and points respectively.
- Added [`CardinalDirection`].
- Added [`Axis`].

# v0.2.1

Expand Down
18 changes: 18 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@ license = "MIT OR Apache-2.0"
rust-version = "1.72"


[lints.clippy]
as_ptr_cast_mut = "warn" # mistake
derive_partial_eq_without_eq = "warn" # mistake
future_not_send = "warn" #async
mutex_integer = "warn" # perf, multithreading
needless_pass_by_ref_mut = "warn" # mistake
read_zero_byte_vec = "warn" # mistake


[workspace.lints.clippy]
as_ptr_cast_mut = "warn" # mistake
derive_partial_eq_without_eq = "warn" # mistake
future_not_send = "warn" # async
mutex_integer = "warn" # perf, multithreading
needless_pass_by_ref_mut = "warn" # mistake
read_zero_byte_vec = "warn" # mistake


[lib]
path = "src/lib.rs"
crate-type = ["lib"]
Expand Down
22 changes: 22 additions & 0 deletions bacon.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,26 @@ command = [
]
need_stdout = false

[jobs.clippy-fix]
command = [
"cargo",
"clippy",
"--fix",
"--allow-staged",
"--all",
"--all-targets",
"--all-features",
"--color",
"always",
"--",
# "--no-deps",
]
need_stdout = false
on_success = "back"
background = true
allow_warnings = true
allow_failures = true

# This job lets you run
# - all tests: bacon test
# - a specific test: bacon test -- config::test_default_files
Expand Down Expand Up @@ -160,3 +180,5 @@ alt-d = "job:doc-open"
shift-d = "job:doc-pub"
r = "rerun"
f5 = "rerun"
c = "job:clippy"
shift-c = "job:clippy-fix"
12 changes: 12 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ cargo_crate_macro := -p $(name)-procedural_macro
# clippy
cargo_clippy := clippy
cargo_clippy_flag := -- -D warnings
fix_flags := --fix --allow-staged

rust_release_flag := --release
# doc
Expand All @@ -33,6 +34,8 @@ rust_doc_targets = --doc
rust_example_flag := --examples
# feature
rust_coverage_feature := --no-default-features --features="serde-serialize"
#nextest
nextest_run := nextest run

rust_stable := +stable
rust_nightly := +nightly
Expand All @@ -51,6 +54,10 @@ git_hooks := $(foreach file, $(notdir $(wildcard tools/git_hook/*)), .git/hooks/
.PHONY: all
all: clippy

.PHONY: fix
fix: $(source_files)
- $(cargo) $(cargo_clippy) $(cargo_all_flag) $(rust_all_targets) $(fix_flags)


.PHONY: build
build: target/debug/$(lib_name)
Expand All @@ -62,6 +69,11 @@ test: $(source_files)
$(cargo) $(cargo_test) $(cargo_all_flag) $(rust_doc_targets)


.PHONY: nextest
nextest: $(source_files)
$(cargo) $(nextest_run) $(cargo_all_flag) $(rust_all_targets)


.PHONY: test_all
test_all: fmt_check test doc_check | clippy

Expand Down
9 changes: 6 additions & 3 deletions procedural_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,13 @@ pub fn implement_direction_list(_item: TokenStream) -> TokenStream {
let mut array_direction = Vec::with_capacity(MAX_DIM);
let mut array_direction_positives = Vec::with_capacity(MAX_DIM);
for j in 0..i {
// SAFETY: #j is smaller than the dimension = #i (later in the proc macro)
array_direction.push(quote! {
Direction { index_dir: #j, is_positive: true },
Direction { index_dir: #j, is_positive: false }
Direction { axis: unsafe{Axis::new_unchecked(#j)}, is_positive: true },
Direction { axis: unsafe{Axis::new_unchecked(#j)}, is_positive: false }
});
array_direction_positives.push(quote! {
Direction { index_dir: #j, is_positive: true }
Direction { axis: unsafe{Axis::new_unchecked(#j)}, is_positive: true }
});
}

Expand All @@ -184,6 +185,8 @@ pub fn implement_direction_list(_item: TokenStream) -> TokenStream {
#[doc=#comment_pos]
const #u_dir_pos_ident: [Direction<#i>; #i] = [ #(#array_direction_positives),* ];

#[allow(unsafe_code)]
#[allow(undocumented_unsafe_blocks)]
impl DirectionList for Direction<#i> {
#[inline]
fn directions() -> &'static [Self] {
Expand Down
138 changes: 138 additions & 0 deletions src/lattice/direction/axis.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
//---------------------------------------
// uses

#[cfg(feature = "serde-serialize")]
use serde::{Deserialize, Serialize};
use utils_lib::{Getter, Sealed};

use super::DirectionIndexing;

//---------------------------------------
// struct definition

/// Represent an axis in the space. There is `D` axis in dimension D. Contrary to
/// [`super::Direction`] and [`super::OrientedDirection`], an [`Axis`]
/// does not have an orientation.
#[derive(Sealed, Debug, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[derive(Getter)]
pub struct Axis<const D: usize> {
/// index of the axis
#[get(Pub, Const, Copy, self_ty = "value")]
index: usize,
}

//---------------------------------------
// main impl block

impl<const D: usize> Axis<D> {
/// Create a new axis. The index should be strictly smaller than `D` to return [`Some`].
/// # Example
/// ```
/// use lattice_qcd_rs::{error::ImplementationError, lattice::Axis};
/// # fn main() -> Result<(), ImplementationError> {
/// assert!(Axis::<0>::new(0).is_none());
/// assert!(Axis::<0>::new(4).is_none());
///
/// let axis = Axis::<1>::new(0).ok_or(ImplementationError::OptionWithUnexpectedNone)?;
/// assert_eq!(axis.index(), 0);
/// assert!(Axis::<1>::new(1).is_none());
///
/// let axis = Axis::<4>::new(3).ok_or(ImplementationError::OptionWithUnexpectedNone)?;
/// assert_eq!(axis.index(), 3);
/// assert!(Axis::<4>::new(4).is_none());
/// assert!(Axis::<4>::new(6).is_none());
/// # Ok(())
/// # }
/// ```
#[inline]
#[must_use]
#[allow(clippy::if_then_some_else_none)] // not possible for const fn
pub const fn new(index: usize) -> Option<Self> {
if index < D {
Some(Self { index })
} else {
None
}
}

#[inline]
#[must_use]
#[allow(unsafe_code)]
pub(super) const unsafe fn new_unchecked(index: usize) -> Self {
Self { index }
}
}

//---------------------------------------
// conversion

// with usize

impl<const D: usize> From<Axis<D>> for usize {
#[inline]
fn from(value: Axis<D>) -> Self {
value.index()
}
}

impl<const D: usize> AsRef<usize> for Axis<D> {
#[inline]
fn as_ref(&self) -> &usize {
&self.index
}
}

// there is no AsMut as is it not safe to give a mut ref to the inner index

//---------------------------------------
// lattice indexing

impl<const D: usize> DirectionIndexing for Axis<D> {
#[inline]
fn to_index(&self) -> usize {
self.index()
}

#[inline]
fn from_index(index: usize) -> Option<Self> {
Self::new(index)
}

#[inline]
fn number_of_elements() -> usize {
D
}
}

#[cfg(test)]
mod test {
use crate::{error::ImplementationError, lattice::Axis};

#[test]
fn axis() -> Result<(), ImplementationError> {
for i in 0..25 {
assert!(Axis::<0>::new(i).is_none());
}
//------------------
assert_eq!(
Axis::<1>::new(0).ok_or(ImplementationError::OptionWithUnexpectedNone)?,
Axis { index: 0 }
);
for i in 1..25 {
assert!(Axis::<1>::new(i).is_none());
}
//------------------
for i in 0..4 {
assert_eq!(
Axis::<4>::new(i).ok_or(ImplementationError::OptionWithUnexpectedNone)?,
Axis { index: i }
);
}
for i in 4..25 {
assert!(Axis::<4>::new(i).is_none());
}

Ok(())
}
}
Loading

0 comments on commit ccd78c7

Please sign in to comment.