use crate::CubeSurfacePoint as CratePt;
use crate::Direction;
use crate::Rotation;
use core::convert::identity as id;
use core::ops::{Div, Mul, MulAssign};
pub type CspLarge = CubeSurfacePoint<true>;
#[doc(hidden)]
#[allow(non_snake_case)]
pub const fn CspLarge(x: CratePt) -> CspLarge {
CubeSurfacePoint::<true>(x)
}
pub type CspSmall = CubeSurfacePoint<false>;
#[doc(hidden)]
#[allow(non_snake_case)]
pub const fn CspSmall(x: CratePt) -> CspSmall {
CubeSurfacePoint::<false>(x)
}
pub type RgpLarge = ReferenceGroupPoint;
#[doc(hidden)]
#[allow(non_snake_case)]
pub const fn RgpLarge(x: crate::ReferenceGroupPoint) -> RgpLarge {
ReferenceGroupPoint(x)
}
pub type OgpLarge = OppositeGroupPoint;
#[doc(hidden)]
#[allow(non_snake_case)]
pub const fn OgpLarge(x: crate::OppositeGroupPoint) -> OgpLarge {
OppositeGroupPoint(x)
}
macro_rules! with_lut {
($truefalse: expr; $fnam: ident $(; $vis:vis)?) => {
#[doc = concat!(
"Please refer to the [function of the same name](crate::",
stringify!(CubeSurfacePoint),
"::",
stringify!($fnam),
") in the basic [`",
stringify!(CubeSurfacePoint),
"`](crate::",
stringify!(CubeSurfacePoint),
")."
)]
$($vis)? const fn $fnam(self) -> Self {
type Csp = CubeSurfacePoint::<{ $truefalse }>;
const fn from_serial_number(x: u8) -> Csp {
CubeSurfacePoint::<{ $truefalse }> (
CratePt::probs_from_u8(x).$fnam()
)
}
const LUT: [Csp; 48] = {
let mut result = [Csp::REFERENCE_POINT; 48];
let mut i = 48;
while i > 0 {
i -= 1;
result[i] = from_serial_number(i as u8);
}
result
};
LUT[self.0 as usize]
}
};
(true; $name: ident, $($names:ident),+ $(; $vis:vis)?) => {
with_lut!(true; $name $(; $vis)?);
with_lut!(true; $($names),+ $(; $vis)?);
};
(false; $name: ident, $($names:ident),+ $(; $vis:vis)?) => {
with_lut!(false; $name $(; $vis)?);
with_lut!(false; $($names),+ $(; $vis)?);
};
}
#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub struct CubeSurfacePoint<const BIG_LUTS: bool>(pub crate::CubeSurfacePoint);
impl<const BIG_LUTS: bool> CubeSurfacePoint<BIG_LUTS> {
pub const REFERENCE_POINT: Self = Self(CratePt::REFERENCE_POINT);
#[doc = concat!(
"Please refer to the [function of the same name]",
"(crate::CubeSurfacePoint::direction", ") in [`CubeSurfacePoint`]."
)]
pub const fn direction(self) -> Direction {
const fn from_serial_number(x: u8) -> Direction {
CratePt::probs_from_u8(x).direction()
}
const LUT: [Direction; 48] = {
let ref_pt = CratePt::REFERENCE_POINT;
let mut result = [ref_pt.direction(); 48];
let mut i = 48;
while i > 0 {
i -= 1;
result[i] = from_serial_number(i as u8);
}
result
};
LUT[self.0 as usize]
}
const fn probs_from_u8(x: u8) -> Self {
Self(CratePt::probs_from_u8(x))
}
}
impl<const BIG_LUTS: bool> From<CratePt> for CubeSurfacePoint<BIG_LUTS> {
fn from(x: CratePt) -> Self {
Self(x)
}
}
impl<const BIG_LUTS: bool> From<CubeSurfacePoint<BIG_LUTS>> for CratePt {
fn from(x: CubeSurfacePoint<BIG_LUTS>) -> Self {
x.0
}
}
impl From<Rotation> for CubeSurfacePoint<true> {
fn from(x: Rotation) -> Self {
Self(x.corresponding_point)
}
}
impl From<Rotation> for CubeSurfacePoint<false> {
fn from(x: Rotation) -> Self {
Self(x.corresponding_point)
}
}
impl CubeSurfacePoint<false> {
with_lut!(false; one_right_angle_cw, one_right_angle_acw, beside,
opposite, opposite_then_beside, flip_sign_of_2, flip_2_and_3; pub);
with_lut!(false; swap_x_y, swap_y_z, swap_z_x, reciprocal);
#[doc = concat!(
"Please refer to the [function of the same name
](crate::CubeSurfacePoint::",
stringify!(n_right_angles),
") in [`CubeSurfacePoint`](crate::CubeSurfacePoint)."
)]
pub const fn n_right_angles<const CLOCKWISE: bool>(self, angle: u8) -> Self {
let mut angle = angle & 0b11;
let mut result = self;
while angle > 0 {
result = if CLOCKWISE {
result.one_right_angle_cw()
} else {
result.one_right_angle_acw()
};
angle -= 1;
}
result
}
#[doc = concat!(
"Please refer to the [function of the same name
](crate::CubeSurfacePoint::",
stringify!(n_right_angles_acw),
") in [`CubeSurfacePoint`](crate::CubeSurfacePoint)."
)]
pub const fn n_right_angles_acw(self, angle: u8) -> Self {
self.n_right_angles::<false>(angle)
}
#[doc = concat!(
"Please refer to the [function of the same name
](crate::CubeSurfacePoint::",
stringify!(n_right_angles_cw),
") in [`CubeSurfacePoint`](crate::CubeSurfacePoint)."
)]
pub const fn n_right_angles_cw(self, angle: u8) -> Self {
self.n_right_angles::<true>(angle)
}
}
impl CubeSurfacePoint<true> {
with_lut!(true; one_right_angle_cw, one_right_angle_acw, beside,
opposite, opposite_then_beside, flip_sign_of_2, flip_2_and_3; pub);
#[doc = concat!(
"Please refer to the [function of the same name
](crate::CubeSurfacePoint::",
stringify!(n_right_angles_cw),
") in [`CubeSurfacePoint`](crate::CubeSurfacePoint)."
)]
pub const fn n_right_angles_cw(self, angle: u8) -> Self {
let angle = angle & 0b11;
type Csp = CubeSurfacePoint<true>;
const LUT: [[Csp; 48]; 4] = {
let mut result = [[Csp::REFERENCE_POINT; 48]; 4];
let mut i: usize = 48 * 4;
while i > 0 {
i -= 1;
result[i % 4][i / 4] = CubeSurfacePoint::<true>(
CratePt::probs_from_u8(i as u8 / 4).n_right_angles_cw(i as u8 % 4),
);
}
result
};
LUT[angle as usize][self.0 as usize]
}
#[doc = concat!(
"Please refer to the [function of the same name
](crate::CubeSurfacePoint::",
stringify!(n_right_angles_acw),
") in [`CubeSurfacePoint`](crate::CubeSurfacePoint)."
)]
pub const fn n_right_angles_acw(self, angle: u8) -> Self {
let angle = angle & 0b11;
type Csp = CubeSurfacePoint<true>;
const LUT: [[Csp; 48]; 4] = {
let mut result = [[Csp::REFERENCE_POINT; 48]; 4];
let mut i: usize = 48 * 4;
while i > 0 {
i -= 1;
result[i % 4][i / 4] = CubeSurfacePoint::<true>(
CratePt::probs_from_u8(i as u8 / 4).n_right_angles_acw(i as u8 % 4),
);
}
result
};
LUT[angle as usize][self.0 as usize]
}
pub fn div_alt(self, divisor: Self) -> Rotation {
const RECIPROCALS: [CubeSurfacePoint<true>; 48] = {
let mut i = 48;
let ref_pt = CubeSurfacePoint::<true>::REFERENCE_POINT;
let mut result = [ref_pt; 48];
while i > 0 {
i -= 1;
let pt = CratePt::probs_from_u8(i as u8);
let siiiigh = ref_pt.0.mul(ref_pt.0.div(pt));
result[i] = CubeSurfacePoint::<true>(siiiigh);
}
result
};
Rotation {
corresponding_point: (Rotation {
corresponding_point: self.0,
} * RECIPROCALS[divisor.0 as usize])
.0,
}
}
}
impl Mul<Rotation> for CubeSurfacePoint<false> {
type Output = Self;
fn mul(self, rot: Rotation) -> Self::Output {
let rot = rot.corresponding_point as u8;
let mut result = self;
if rot & 0b001_000 != 0 {
result = result.swap_z_x();
}
if rot & 0b010_000 != 0 {
result = result.swap_y_z();
}
if rot & 0b100_000 != 0 {
result = result.swap_x_y();
}
let rot = rot & 7;
Self::probs_from_u8(result.0 as u8 ^ rot)
}
}
impl Mul<Rotation> for CubeSurfacePoint<true> {
type Output = Self;
fn mul(self, rot: Rotation) -> Self::Output {
type Csp = CubeSurfacePoint<true>;
const fn from_serial_number(x: u16) -> Csp {
let rot = crate::Rotation {
corresponding_point: CratePt::probs_from_u8((x / 48) as u8),
};
let surface_point = CratePt::probs_from_u8((x % 48) as u8);
CubeSurfacePoint::<true>(rot.mul(surface_point))
}
const LUT: [[Csp; 48]; 48] = {
let mut result = [[Csp::REFERENCE_POINT; 48]; 48];
let mut i = 48 * 48;
while i > 0 {
i -= 1;
result[i / 48][i % 48] = from_serial_number(i as u16);
}
result
};
LUT[rot.corresponding_point as usize][self.0 as usize]
}
}
impl MulAssign<Rotation> for CubeSurfacePoint<true> {
fn mul_assign(&mut self, rot: Rotation) {
*self = *self * rot;
}
}
impl MulAssign<Rotation> for CubeSurfacePoint<false> {
fn mul_assign(&mut self, rot: Rotation) {
*self = *self * rot;
}
}
impl Mul<CubeSurfacePoint<true>> for Rotation {
type Output = CubeSurfacePoint<true>;
fn mul(self, cub_sur_pt: Self::Output) -> Self::Output {
cub_sur_pt * self
}
}
impl Mul<CubeSurfacePoint<false>> for Rotation {
type Output = CubeSurfacePoint<false>;
fn mul(self, cub_sur_pt: Self::Output) -> Self::Output {
cub_sur_pt * self
}
}
impl Div for CubeSurfacePoint<false> {
type Output = Rotation;
fn div(self, divisor: Self) -> Self::Output {
let recip = divisor.reciprocal();
let rot = Rotation {
corresponding_point: self.0,
};
Rotation {
corresponding_point: (recip.mul(rot)).0,
}
}
}
impl Div for CubeSurfacePoint<true> {
type Output = Rotation;
fn div(self, divisor: Self) -> Self::Output {
const fn from_serial_number(x: u16) -> Rotation {
let divisor = CratePt::probs_from_u8((x / 48) as u8);
let point = CratePt::probs_from_u8((x % 48) as u8);
point.div(divisor)
}
const LUT: [[Rotation; 48]; 48] = {
let temp_rot = Rotation {
corresponding_point: CratePt::REFERENCE_POINT,
};
let mut result = [[temp_rot; 48]; 48];
let mut i = 48 * 48;
while i > 0 {
i -= 1;
result[i % 48][i / 48] = from_serial_number(i as u16);
}
result
};
let divisor = divisor.0 as usize;
let dividend = self.0 as usize;
LUT[dividend][divisor]
}
}
use crate::{ImproperRotation, ProperRotation};
impl Mul<ProperRotation> for CubeSurfacePoint<false> {
type Output = Self;
fn mul(self, x: ProperRotation) -> Self {
let rot: Rotation = x.into();
rot * self
}
}
impl Mul<ProperRotation> for CubeSurfacePoint<true> {
type Output = Self;
fn mul(self, x: ProperRotation) -> Self {
let rot: Rotation = x.into();
rot * self
}
}
impl Mul<ImproperRotation> for CubeSurfacePoint<false> {
type Output = Self;
fn mul(self, x: ImproperRotation) -> Self {
let rot: Rotation = x.into();
rot * self
}
}
impl Mul<ImproperRotation> for CubeSurfacePoint<true> {
type Output = Self;
fn mul(self, x: ImproperRotation) -> Self {
let rot: Rotation = x.into();
rot * self
}
}
impl MulAssign<ProperRotation> for CubeSurfacePoint<true> {
fn mul_assign(&mut self, x: ProperRotation) {
*self = *self * x;
}
}
impl MulAssign<ImproperRotation> for CubeSurfacePoint<true> {
fn mul_assign(&mut self, x: ImproperRotation) {
*self = *self * x;
}
}
fn mul_rots_big_luts(rot_1: Rotation, rot_2: Rotation) -> Rotation {
let corr_point: CubeSurfacePoint<true> = rot_2.into();
(rot_1 * corr_point).into()
}
fn div_rots_big_luts(rot_1: Rotation, rot_2: Rotation) -> Rotation {
let corr_point_1: CubeSurfacePoint<true> = rot_1.into();
let corr_point_2: CubeSurfacePoint<true> = rot_2.into();
corr_point_1 / corr_point_2
}
fn mul_rots_small_luts(rot_1: Rotation, rot_2: Rotation) -> Rotation {
let corr_point: CubeSurfacePoint<false> = rot_2.into();
(rot_1 * corr_point).into()
}
fn div_rots_small_luts(rot_1: Rotation, rot_2: Rotation) -> Rotation {
let corr_point_1: CubeSurfacePoint<false> = rot_1.into();
let corr_point_2: CubeSurfacePoint<false> = rot_2.into();
corr_point_1 / corr_point_2
}
pub fn multiply_rotations_luts<const BIG: bool>(rot_1: Rotation, rot_2: Rotation) -> Rotation {
[mul_rots_small_luts, mul_rots_big_luts][BIG as usize](rot_1, rot_2)
}
pub fn divide_rotations_luts<const BIG: bool>(rot_1: Rotation, rot_2: Rotation) -> Rotation {
[div_rots_small_luts, div_rots_big_luts][BIG as usize](rot_1, rot_2)
}
impl MulAssign<ProperRotation> for CubeSurfacePoint<false> {
fn mul_assign(&mut self, x: ProperRotation) {
*self = *self * x;
}
}
impl MulAssign<ImproperRotation> for CubeSurfacePoint<false> {
fn mul_assign(&mut self, x: ImproperRotation) {
*self = *self * x;
}
}
macro_rules! with_lut {
($us: ty, $out: path, $fnam: ident, $convert: ident) => {
#[doc = concat!(
"Please refer to the [function of the same name
](crate::CubeSurfacePoint::",
stringify!($fnam),
") in
[`CubeSurfacePoint`](crate::CubeSurfacePoint)."
)]
pub const fn $fnam(self) -> $out {
const fn from_serial_number (i: usize) -> $out {
$convert(<$us>::index_to_self(i).0.$fnam())
}
const LUT: [$out; 24] = {
let mut result = [from_serial_number(0); 24];
let mut i = 24;
while i > 0 {
i -= 1;
result[i] = from_serial_number(i);
}
result
};
LUT[self.0 as usize >> 1]
}
};
(angles; $us: path, $fnam: ident) => {
#[doc = concat!(
"Please refer to the [function of the same name
](crate::CubeSurfacePoint::",
stringify!($fnam),
") in
[`CubeSurfacePoint`](crate::CubeSurfacePoint)."
)]
pub const fn $fnam(self, angle:u8) -> Self {
let angle = angle & 0b11;
const fn from_serial_number (i: usize) -> $us {
$us(<$us>::index_to_self(i / 4).0.$fnam((i as u8) % 4))
}
const LUT: [[$us; 24]; 4] = {
let mut result = [[from_serial_number(0); 24]; 4];
let mut i: usize = 24 * 4;
while i > 0 {
i -= 1;
result[i % 4][i / 4] = from_serial_number(i);
}
result
};
LUT[angle as usize][self.0 as usize >> 1]
}
};
(muldiv; $us: ty, $other: ty, $out: ty, $fnam: ident, $out_to_out: ident $(; $const:tt)? $(.$siiiigh: tt)?) => {
#[doc = concat!(
"Please refer to the [function of the same name](crate::",
stringify!($us),
"::",
stringify!($fnam),
") in the basic [`",
stringify!($us),
"`](crate::",
stringify!($us),
")."
)]
$(pub $const)? fn $fnam(self, other: $other) -> $out {
const fn from_serial_number(x: usize) -> $out {
let us = <$us>::index_to_self(x / 24).0;
let other = <$other>::index_to_self(x % 24) $(. $siiiigh)?;
$out_to_out(us.$fnam(other))
}
const LUT: [[$out; 24]; 24] = {
let mut result = [[from_serial_number(0); 24]; 24];
let mut i = 24 * 24;
while i > 0 {
i -= 1;
result[i / 24][i % 24] = from_serial_number(i);
}
result
};
LUT[self.0 as usize >> 1][other.self_to_index() as usize >> 1]
}
};
(everything; $us: ty, $others:ty, $check: ident,
$self_to_self:ident, $other_to_other: ident $(,)?) => {
const fn index_to_self(x: usize) -> $us {
let x = (x as u8) * 2;
let pt_1 = CratePt::probs_from_u8(x);
let pt_2 = CratePt::probs_from_u8(x ^ 1);
let result = match (pt_1.$check(), pt_2.$check()) {
(Ok(point), Err(_)) => point,
(Err(_), Ok(point)) => point,
_ => crate::unreachable_semichecked(),
};
$self_to_self(result)
}
const fn self_to_index(self) -> usize {
self.0 as usize
}
with_lut!($us, Direction, direction, id);
with_lut!($us, $others, beside, $other_to_other);
with_lut!($us, $others, opposite, $other_to_other);
with_lut!($us, $others, flip_sign_of_2, $other_to_other);
with_lut!($us, $us, opposite_then_beside, $self_to_self);
with_lut!($us, $us, flip_2_and_3, $self_to_self);
with_lut!($us, $us, one_right_angle_cw, $self_to_self);
with_lut!($us, $us, one_right_angle_acw, $self_to_self);
with_lut!(angles; $us, n_right_angles_cw);
with_lut!(angles; $us, n_right_angles_acw);
with_lut!(muldiv; $us, $us, ProperRotation, div_prop, id; const .0);
with_lut!(muldiv; $us, $others, ImproperRotation, div_improp, id; const .0);
with_lut!(muldiv; $us, ProperRotation, $us, mul_prop, $self_to_self; const);
with_lut!(muldiv; $us, ImproperRotation, $others, mul_improp, $other_to_other; const);
};
(impls; $us: ty, $others: ty) => {
impl Mul<ProperRotation> for $us {
type Output = Self;
fn mul (self, x: ProperRotation) -> Self::Output {
self.mul_prop(x)
}
}
impl MulAssign<ProperRotation> for $us {
fn mul_assign(&mut self, x: ProperRotation) {
*self = *self * x;
}
}
impl Mul<ImproperRotation> for $us {
type Output = $others;
fn mul (self, x: ImproperRotation) -> Self::Output {
self.mul_improp(x)
}
}
impl Mul<$us> for ProperRotation {
type Output = $us;
fn mul (self, x: $us) -> Self::Output {
x * self
}
}
impl Mul<$us> for ImproperRotation {
type Output = $others;
fn mul (self, x: $us) -> Self::Output {
x * self
}
}
impl Div for $us {
type Output = ProperRotation;
fn div (self, x: Self) -> Self::Output {
self.div_prop(x)
}
}
impl Div<$others> for $us {
type Output = ImproperRotation;
fn div (self, x: $others) -> Self::Output {
self.div_improp(x)
}
}
};
(impls; $us: ty, $others: ty, $check: ident, $self_to_self: ident, $other_to_other: ident) => {
impl From<$us> for CratePt {
fn from(x: $us) -> CratePt {
x.0.downcast()
}
}
impl TryFrom<CratePt> for $us {
#[doc = concat!(
"If a certain [`CubeSurfacePoint`] does not belong to the [`",
stringify!($us),
"`]s, it must by necessity belong to the [`",
stringify!($others),
"`]s."
)]
type Error = $others;
fn try_from(x: CratePt) -> Result<Self, Self::Error> {
match x.$check() {
Ok(point) => {
Ok($self_to_self(point))
},
Err(point) => {
Err($other_to_other(point))
},
}
}
}
};
}
#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub struct ReferenceGroupPoint(pub crate::ReferenceGroupPoint);
#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub struct OppositeGroupPoint(pub crate::OppositeGroupPoint);
const fn rgp_to_rgp(x: crate::ReferenceGroupPoint) -> ReferenceGroupPoint {
ReferenceGroupPoint(x)
}
const fn ogp_to_ogp(x: crate::OppositeGroupPoint) -> OppositeGroupPoint {
OppositeGroupPoint(x)
}
impl From<ProperRotation> for ReferenceGroupPoint {
fn from(x: ProperRotation) -> Self {
Self(x.corresponding_point)
}
}
impl From<ImproperRotation> for OppositeGroupPoint {
fn from(x: ImproperRotation) -> Self {
Self(x.corresponding_point)
}
}
impl From<CubeSurfacePoint<true>> for Rotation {
fn from(corresponding_point: CubeSurfacePoint<true>) -> Self {
Self {
corresponding_point: corresponding_point.0,
}
}
}
impl From<CubeSurfacePoint<false>> for Rotation {
fn from(corresponding_point: CubeSurfacePoint<false>) -> Self {
Self {
corresponding_point: corresponding_point.0,
}
}
}
impl From<ReferenceGroupPoint> for ProperRotation {
fn from(corresponding_point: ReferenceGroupPoint) -> Self {
Self {
corresponding_point: corresponding_point.0,
}
}
}
impl From<OppositeGroupPoint> for ImproperRotation {
fn from(corresponding_point: OppositeGroupPoint) -> Self {
Self {
corresponding_point: corresponding_point.0,
}
}
}
impl ProperRotation {
const fn index_to_self(x: usize) -> Self {
Self {
corresponding_point: ReferenceGroupPoint::index_to_self(x).0,
}
}
const fn self_to_index(self) -> usize {
self.corresponding_point as usize
}
}
impl ImproperRotation {
const fn index_to_self(x: usize) -> Self {
Self {
corresponding_point: OppositeGroupPoint::index_to_self(x).0,
}
}
const fn self_to_index(self) -> usize {
self.corresponding_point as usize
}
}
impl ReferenceGroupPoint {
with_lut!(
everything;
ReferenceGroupPoint,
OppositeGroupPoint,
determine_group,
rgp_to_rgp,
ogp_to_ogp,
);
pub fn div_alt(self, x: Self) -> ProperRotation {
const LUT: [ReferenceGroupPoint; 24] = {
let mut result = [ReferenceGroupPoint::index_to_self(0); 24];
let mut i = 24;
while i > 0 {
i -= 1;
result[i] = ReferenceGroupPoint(
ReferenceGroupPoint::index_to_self(0)
.div_prop(ReferenceGroupPoint::index_to_self(i))
.corresponding_point,
);
}
result
};
let corresponding_point = ProperRotation {
corresponding_point: self.0,
} * LUT[x.0 as usize >> 1];
ProperRotation {
corresponding_point: corresponding_point.0,
}
}
}
impl OppositeGroupPoint {
with_lut!(
everything;
OppositeGroupPoint,
ReferenceGroupPoint,
determine_antigroup,
ogp_to_ogp,
rgp_to_rgp,
);
#[deprecated(note = "It is not yet clear whether this function should \
also exist for `OppositeGroupPoint`s.")]
pub fn div_alt(self, x: Self) -> ProperRotation {
const LUT: [OppositeGroupPoint; 24] = {
let mut result = [OppositeGroupPoint::index_to_self(0); 24];
let mut i = 24;
while i > 0 {
i -= 1;
result[i] = OppositeGroupPoint(
ReferenceGroupPoint::index_to_self(0)
.div_improp(OppositeGroupPoint::index_to_self(i))
.corresponding_point,
);
}
result
};
let corresponding_point = ImproperRotation {
corresponding_point: self.0,
} * LUT[x.0 as usize >> 1];
ProperRotation {
corresponding_point: corresponding_point.0,
}
}
}
with_lut!(impls; ReferenceGroupPoint, OppositeGroupPoint);
with_lut!(impls; OppositeGroupPoint, ReferenceGroupPoint);
with_lut!(impls;
ReferenceGroupPoint,
OppositeGroupPoint,
determine_group,
rgp_to_rgp,
ogp_to_ogp
);
with_lut!(impls;
OppositeGroupPoint,
ReferenceGroupPoint,
determine_antigroup,
ogp_to_ogp,
rgp_to_rgp
);