generic の代用
薬局でもジェネリックを勧められても拒否するし、Fortran 文法でもジェネリクス導入を拒否しますw
そもそも単精度では精度を保つため、積の結果だけ倍精度使うとか、完全に同じソースではすまないことがあります。
とはいえ、ジェネリクスのように同じコードの繰り返しを1回で済ませられなくても、実装部は同じ内容のコピペを繰り返して、インターフェース前後だけ最小限いじってすませられないか、少し考えてみました。
submodule を使うと、定義の向きなどが素直でいいのですが、名前の重複に工夫が必要です。ここでは module のみで考えてみることにします。
Fortran
単精度・倍精度・四倍精度の module を三つそれぞれに対して用意しますが、モジュール名と定数以外は共通とします。それらを親モジュールに集めて、名前のダブりを use 文で回避して、総称名にします。
- 作者: Michael Metcalf,John Reid,Malcolm Cohen
- 出版社/メーカー: Oxford Univ Pr
- 発売日: 2018/11/06
- メディア: ハードカバー
- この商品を含むブログを見る
module mod00 implicit none integer, parameter :: ks = kind(1.0e0) integer, parameter :: kd = kind(1.0d0) integer, parameter :: kq = kind(1.0q0) end module mod00 module mods use mod00 implicit none integer, parameter :: kn = ks contains real(kn) function fun(x) result(res) real(kn), intent(in):: x res=x end end module modd use mod00 implicit none integer, parameter :: kn = kd contains real(kn) function fun(x) result(res) real(kn), intent(in):: x res=x end end module modq use mod00 implicit none integer, parameter :: kn = kq contains real(kn) function fun(x) result(res) real(kn), intent(in):: x res=x end end module mod use mods, only: fun_s=>fun use modd, only: fun_d=>fun use modq, only: fun_q=>fun interface fun procedure :: fun_s, fun_d, fun_q end interface end module mod program test use mod implicit none print *, fun(1.0e0) print *, fun(1.0d0) print *, fun(1.0q0) end program
実行結果
1.000000 1.00000000000000 1.00000000000000000000000000000000