- 628 名前:デフォルトの名無しさん mailto:sage [2022/06/12(日) 20:36:02.36 ID:nrxswUhC.net]
- >>562 >>566
CheckedAddAssignにこだわる必要はないため、発想を転換して、 checked_add()の原関数であるoverflowing_add()を用いることで、 overflowing_add_assign()を用意して同じようにbool値を返せば解決する 具体的には以下のように引数はadd_assign()と同じでbool値を返せばよい trait OverflowingAddAssign { fn overflowing_add_assign(&mut self, rhs: &Self) -> bool; } オーバーフローするi8型〜u128型にはoverflowing_add()があるため実装はこうなる let is_overflow; (*self, is_overflow) = self.overflowing_add(*rhs); is_overflow この3行のコードでちゃんと最適化されるかどうかを確認するため、 単純にadd_assignを用いた場合、すなわち「*self += rhs」と比較すると https://godbolt.org/z/WP3En8xM8 のアセンブリ出力となり、オーバーフローを返す以外は同一に最適化されることが確認できる 一方でオーバーフローしないBigUintなどの型への実装はこうなる *self += rhs; false つまりオーバーフローの結果として常にfalseを返すので、 こちらは使う側でオーバーフローの扱いが消えてadd_assign部分のみに最適化される したがってこのOverflowingAddAssignを用いてジェネリックに書けば、 どちらの型の場合であっても、非ジェネリックに書いた時と同一コードとなる
|

|