Skip to content

Commit 54523c6

Browse files
committed
broked
1 parent 84686d3 commit 54523c6

11 files changed

Lines changed: 178 additions & 252 deletions

File tree

include/cnl/_impl/scaled/binary_operator.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
namespace cnl {
2020
template<_impl::binary_op Operator, integer LhsRep, integer RhsRep, scaled_tag Scale>
2121
// requires(!std::is_same_v<Operator, _impl::divide_op>)
22-
struct
23-
custom_operator<Operator, op_value<LhsRep, Scale>, op_value<RhsRep, Scale>>
22+
struct custom_operator<Operator, op_value<LhsRep, Scale>, op_value<RhsRep, Scale>>
2423
: Operator {
2524
};
2625

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
2+
// Copyright John McFarlane 2019.
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// (See accompanying file ../LICENSE_1_0.txt or copy at
5+
// http://www.boost.org/LICENSE_1_0.txt)
6+
7+
#if !defined(CNL_IMPL_SCALED_CONVERT_OPERATOR_H)
8+
#define CNL_IMPL_SCALED_CONVERT_OPERATOR_H
9+
10+
#include "../../floating_point.h"
11+
#include "../../fraction.h"
12+
#include "../../integer.h"
13+
#include "../custom_operator/native_tag.h"
14+
#include "../num_traits/fixed_width_scale.h"
15+
#include "../num_traits/scale.h"
16+
#include "../power_value.h"
17+
#include "../scaled_integer/definition.h"
18+
#include "is_scaled_tag.h"
19+
20+
/// compositional numeric library
21+
namespace cnl {
22+
// integer -> floating
23+
template<integer Src, scaled_tag SrcScale, floating_point Dest, scaled_tag DestScale>
24+
requires(_impl::radix_v<SrcScale> == _impl::radix_v<DestScale>) struct custom_operator<
25+
_impl::convert_op,
26+
op_value<Src, SrcScale>,
27+
op_value<Dest, DestScale>> {
28+
[[nodiscard]] constexpr auto operator()(Src const& from) const
29+
{
30+
return Dest(from)
31+
* _impl::power_value<Dest, _impl::exponent_v<SrcScale> - _impl::exponent_v<DestScale>, _impl::radix_v<SrcScale>>();
32+
}
33+
};
34+
35+
// floating -> integer
36+
template<floating_point Input, scaled_tag SrcScale, integer Result, scaled_tag DestScale>
37+
requires(_impl::radix_v<SrcScale> == _impl::radix_v<DestScale>) struct custom_operator<
38+
_impl::convert_op,
39+
op_value<Input, SrcScale>,
40+
op_value<Result, DestScale>> {
41+
[[nodiscard]] constexpr auto operator()(Input const& from) const
42+
{
43+
return static_cast<Result>(
44+
from * _impl::power_value<Input, _impl::exponent_v<SrcScale> - _impl::exponent_v<DestScale>, _impl::radix_v<SrcScale>>());
45+
}
46+
};
47+
48+
// integer -> integer (same Radix)
49+
template<integer Input, scaled_tag SrcScale, integer Result, scaled_tag DestScale>
50+
requires(_impl::radix_v<SrcScale> == _impl::radix_v<DestScale>) struct custom_operator<
51+
_impl::convert_op,
52+
op_value<Input, SrcScale>, op_value<Result, DestScale>> {
53+
[[nodiscard]] constexpr auto operator()(Input const& from) const
54+
{
55+
// when converting *from* scaled_integer
56+
return static_cast<Result>(_impl::scale<_impl::exponent_v<SrcScale> - _impl::exponent_v<DestScale>, _impl::radix_v<SrcScale>>(
57+
_impl::from_value<Result>(from)));
58+
}
59+
};
60+
61+
// integer -> integer (different Ridixes)
62+
template<
63+
integer Input, scaled_tag SrcScale,
64+
integer Result, scaled_tag DestScale>
65+
struct custom_operator<
66+
_impl::convert_op,
67+
op_value<Input, SrcScale>,
68+
op_value<Result, DestScale>> {
69+
[[nodiscard]] constexpr auto operator()(Input const& from) const
70+
{
71+
constexpr auto src_exponent{_impl::exponent_v<SrcScale>};
72+
constexpr auto src_radix{_impl::radix_v<SrcScale>};
73+
constexpr auto dest_exponent{_impl::exponent_v<DestScale>};
74+
constexpr auto dest_radix{_impl::radix_v<DestScale>};
75+
76+
auto result{_impl::from_value<Result>(from)};
77+
if constexpr (src_exponent > 0) {
78+
result = _impl::scale<src_exponent, src_radix>(result);
79+
}
80+
if constexpr (dest_exponent < 0) {
81+
result = _impl::scale<-dest_exponent, dest_radix>(result);
82+
}
83+
if constexpr (src_exponent < 0) {
84+
result = _impl::scale<src_exponent, src_radix>(result);
85+
}
86+
if constexpr (dest_exponent > 0) {
87+
result = _impl::scale<-dest_exponent, dest_radix>(result);
88+
}
89+
return result;
90+
}
91+
};
92+
93+
// shims between equivalent tags
94+
template<typename Input, typename Result, scaled_tag DestScale>
95+
struct custom_operator<_impl::convert_op, op_value<Input>, op_value<Result, DestScale>>
96+
: custom_operator<
97+
_impl::convert_op,
98+
op_value<Input, power<0, _impl::radix_v<DestScale>>>,
99+
op_value<Result, DestScale>> {
100+
};
101+
102+
template<typename Input, scaled_tag SrcScale, typename Result>
103+
struct custom_operator<_impl::convert_op, op_value<Input, SrcScale>, op_value<Result>>
104+
: custom_operator<_impl::convert_op, op_value<Input, SrcScale>, op_value<Result, power<0, _impl::radix_v<SrcScale>>>> {
105+
};
106+
107+
////////////////////////////////////////////////////////////////////////////////
108+
// conversion from fraction
109+
110+
namespace _impl {
111+
// template<integer Rep, scaled_tag Scale>
112+
// [[nodiscard]] constexpr auto not_scaled_integer(
113+
// scaled_integer<Rep, Scale> const& f)
114+
// {
115+
// return _impl::to_rep(f);
116+
// }
117+
118+
// template<integer Rep, scaled_tag Scale>
119+
// inline constexpr auto exponent_v<scaled_integer<Rep, Scale>> = Exponent;
120+
121+
template<class Quotient, class Dividend, class Divisor>
122+
struct exponent_shift
123+
: std::integral_constant<
124+
int,
125+
_impl::exponent_v<Dividend> - _impl::exponent_v<Divisor> - _impl::exponent_v<Quotient>> {
126+
};
127+
}
128+
129+
template<
130+
typename SrcNumerator, typename SrcDenominator,
131+
typename Dest, scaled_tag DestScale>
132+
struct custom_operator<
133+
_impl::convert_op,
134+
op_value<cnl::fraction<SrcNumerator, SrcDenominator>, typename DestScale::identity>,
135+
op_value<Dest, DestScale>> {
136+
[[nodiscard]] constexpr auto operator()(
137+
cnl::fraction<SrcNumerator, SrcDenominator> const& from) const
138+
{
139+
static_assert(_impl::exponent_v<Dest> == 0, "TODO");
140+
141+
return static_cast<Dest>(
142+
_impl::fixed_width_scale<
143+
_impl::exponent_v<SrcNumerator> - _impl::exponent_v<SrcDenominator> - _impl::exponent_v<DestScale>,
144+
_impl::radix_v<DestScale>>(static_cast<Dest>(_impl::not_scaled_integer(from.numerator)))
145+
/ _impl::not_scaled_integer(from.denominator));
146+
}
147+
};
148+
}
149+
150+
#endif // CNL_IMPL_SCALED_CONVERT_OPERATOR_H

include/cnl/_impl/scaled/power.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
#define CNL_IMPL_SCALED_POWER_H
99

1010
#include "binary_operator.h"
11+
#include "convert_operator.h"
1112
#include "is_same_tag_family.h"
1213
#include "is_scaled_tag.h"
1314
#include "is_tag.h"
14-
#include "power/convert_operator.h"
15+
#include "unary_operator.h"
1516
#include "power/definition.h"
1617
#include "power/inc_dec_operator.h"
1718
#include "power/is_scaled_tag.h"
18-
#include "power/unary_operator.h"
1919

2020
#endif // CNL_IMPL_SCALED_POWER_H

include/cnl/_impl/scaled/power/convert_operator.h

Lines changed: 0 additions & 143 deletions
This file was deleted.

include/cnl/_impl/scaled/quasi_exact.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
#define CNL_IMPL_SCALED_QUASI_EXACT_H
99

1010
#include "binary_operator.h"
11+
#include "convert_operator.h"
1112
#include "is_same_tag_family.h"
1213
#include "is_scaled_tag.h"
1314
#include "is_tag.h"
15+
#include "unary_operator.h"
1416
#include "quasi_exact/binary_operator.h"
15-
#include "quasi_exact/convert_operator.h"
1617
#include "quasi_exact/definition.h"
1718
#include "quasi_exact/inc_dec_operator.h"
1819
#include "quasi_exact/is_scaled_tag.h"
19-
#include "quasi_exact/unary_operator.h"
2020

2121
#endif // CNL_IMPL_SCALED_QUASI_EXACT_H

include/cnl/_impl/scaled/quasi_exact/convert_operator.h

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)