1+ #:include "common.fypp"
2+ #:set KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + CMPLX_KINDS_TYPES
13module stdlib_linalg_state
4+ !! Version: experimental
5+ !!
6+ !! Provides a state/error handling derived type for advanced error handling of
7+ !! BLAS/LAPACK based linear algebra procedures
8+ !! !! ([Specification](../page/specs/stdlib_linalg.html))
29 use stdlib_linalg_constants,only:ilp,lk
3- use iso_fortran_env,only:real32,real64,real128,int8,int16,int32,int64,stderr => error_unit
10+ use stdlib_kinds
11+ use stdlib_io
12+ use iso_fortran_env,only: stderr => error_unit
413 implicit none(type,external)
514 private
615
@@ -143,7 +152,7 @@ module stdlib_linalg_state
143152
144153 end function state_print
145154
146- !> Cleanup object
155+ !> Cleanup the object
147156 elemental subroutine state_destroy(this)
148157 class(linalg_state),intent(inout) :: this
149158
@@ -165,62 +174,84 @@ module stdlib_linalg_state
165174 state_is_error = this%state /= LINALG_SUCCESS
166175 end function state_is_error
167176
168- !> Compare an error flag with an integer
177+ !> Compare an error state with an integer flag
169178 elemental logical(lk) function state_eq_flag(err,flag)
170179 type(linalg_state),intent(in) :: err
171180 integer,intent(in) :: flag
172181 state_eq_flag = err%state == flag
173182 end function state_eq_flag
183+
184+ !> Compare an integer flag with the error state
174185 elemental logical(lk) function flag_eq_state(flag,err)
175186 integer,intent(in) :: flag
176187 type(linalg_state),intent(in) :: err
177188 flag_eq_state = err%state == flag
178189 end function flag_eq_state
190+
191+ !> Compare the error state with an integer flag
179192 elemental logical(lk) function state_neq_flag(err,flag)
180193 type(linalg_state),intent(in) :: err
181194 integer,intent(in) :: flag
182195 state_neq_flag = .not. state_eq_flag(err,flag)
183196 end function state_neq_flag
197+
198+ !> Compare an integer flag with the error state
184199 elemental logical(lk) function flag_neq_state(flag,err)
185200 integer,intent(in) :: flag
186201 type(linalg_state),intent(in) :: err
187202 flag_neq_state = .not. state_eq_flag(err,flag)
188203 end function flag_neq_state
204+
205+ !> Compare the error state with an integer flag
189206 elemental logical(lk) function state_lt_flag(err,flag)
190207 type(linalg_state),intent(in) :: err
191208 integer,intent(in) :: flag
192209 state_lt_flag = err%state < flag
193210 end function state_lt_flag
211+
212+ !> Compare the error state with an integer flag
194213 elemental logical(lk) function state_le_flag(err,flag)
195214 type(linalg_state),intent(in) :: err
196215 integer,intent(in) :: flag
197216 state_le_flag = err%state <= flag
198217 end function state_le_flag
218+
219+ !> Compare an integer flag with the error state
199220 elemental logical(lk) function flag_lt_state(flag,err)
200221 integer,intent(in) :: flag
201222 type(linalg_state),intent(in) :: err
202223 flag_lt_state = err%state < flag
203224 end function flag_lt_state
225+
226+ !> Compare an integer flag with the error state
204227 elemental logical(lk) function flag_le_state(flag,err)
205228 integer,intent(in) :: flag
206229 type(linalg_state),intent(in) :: err
207230 flag_le_state = err%state <= flag
208231 end function flag_le_state
232+
233+ !> Compare the error state with an integer flag
209234 elemental logical(lk) function state_gt_flag(err,flag)
210235 type(linalg_state),intent(in) :: err
211236 integer,intent(in) :: flag
212237 state_gt_flag = err%state > flag
213238 end function state_gt_flag
239+
240+ !> Compare the error state with an integer flag
214241 elemental logical(lk) function state_ge_flag(err,flag)
215242 type(linalg_state),intent(in) :: err
216243 integer,intent(in) :: flag
217244 state_ge_flag = err%state >= flag
218245 end function state_ge_flag
246+
247+ !> Compare an integer flag with the error state
219248 elemental logical(lk) function flag_gt_state(flag,err)
220249 integer,intent(in) :: flag
221250 type(linalg_state),intent(in) :: err
222251 flag_gt_state = err%state > flag
223252 end function flag_gt_state
253+
254+ !> Compare an integer flag with the error state
224255 elemental logical(lk) function flag_ge_state(flag,err)
225256 integer,intent(in) :: flag
226257 type(linalg_state),intent(in) :: err
@@ -313,65 +344,24 @@ module stdlib_linalg_state
313344
314345 select type (aa => a)
315346
347+ !> String type
316348 type is (character(len=*))
317-
318349 msg = trim(msg)//sep(:ls)//aa
319350
320- type is (integer(int8))
321-
322- write (buffer,'(i0)') aa
323- msg = trim(msg)//sep(:ls)//trim(adjustl(buffer))
324-
325- type is (integer(int16))
326-
327- write (buffer,'(i0)') aa
328- msg = trim(msg)//sep(:ls)//trim(adjustl(buffer))
329-
330- type is (integer(int32))
331-
351+ !> Numeric types
352+ #:for k1, t1 in KINDS_TYPES
353+ type is (${t1}$)
354+ #:if 'real' in t1
355+ write (buffer,FMT_REAL_${k1}$) aa
356+ #:elif 'complex' in t1
357+ write (buffer,FMT_COMPLEX_${k1}$) aa
358+ #:else
332359 write (buffer,'(i0)') aa
360+ #:endif
333361 msg = trim(msg)//sep(:ls)//trim(adjustl(buffer))
334362
335- type is (integer(int64))
336-
337- write (buffer,'(i0)') aa
338- msg = trim(msg)//sep(:ls)//trim(adjustl(buffer))
339-
340- type is (real(real32))
341-
342- write (buffer,'(es15.8e2)') aa
343- msg = trim(msg)//sep(:ls)//trim(adjustl(buffer))
344-
345- type is (real(real64))
346-
347- write (buffer,'(es24.16e3)') aa
348- msg = trim(msg)//sep(:ls)//trim(adjustl(buffer))
349-
350- type is (real(real128))
351-
352- write (buffer,'(es44.35e4)') aa
353- msg = trim(msg)//sep(:ls)//trim(adjustl(buffer))
354-
355- type is (complex(real32))
356-
357- write (buffer,'(es15.8e2)') aa%re
358- write (buffer2,'(es15.8e2)') aa%im
359- msg = trim(msg)//sep(:ls)//'('//trim(adjustl(buffer))//','//trim(adjustl(buffer2))//')'
360-
361- type is (complex(real64))
362-
363- write (buffer,'(es24.16e3)') aa%re
364- write (buffer2,'(es24.16e3)') aa%im
365- msg = trim(msg)//sep(:ls)//'('//trim(adjustl(buffer))//','//trim(adjustl(buffer2))//')'
366-
367- type is (complex(real128))
368-
369- write (buffer,'(es44.35e4)') aa%re
370- write (buffer2,'(es44.35e4)') aa%im
371- msg = trim(msg)//sep(:ls)//'('//trim(adjustl(buffer))//','//trim(adjustl(buffer2))//')'
372-
363+ #:endfor
373364 class default
374-
375365 msg = trim(msg)//' <ERROR: INVALID TYPE>'
376366
377367 end select
@@ -384,7 +374,7 @@ module stdlib_linalg_state
384374 character(len=*),intent(inout) :: msg
385375
386376 integer :: j,ls
387- character(len=MSG_LENGTH) :: buffer,buffer2
377+ character(len=MSG_LENGTH) :: buffer,buffer2,buffer_format
388378 character(len=2) :: sep
389379
390380 if (.not. present(a)) return
@@ -400,111 +390,33 @@ module stdlib_linalg_state
400390 ! Do not call append(msg(aa(j))), it will crash gfortran
401391 select type (aa => a)
402392
393+ !> Strings (cannot use string_type due to `sequence`)
403394 type is (character(len=*))
404-
405395 msg = trim(msg)//adjustl(aa(1))
406396 do j = 2,size(a)
407397 msg = trim(msg)//sep(:ls)//adjustl(aa(j))
408398 end do
409399
410- type is (integer(int8))
411-
412- write (buffer,'(i0)') aa(1)
413- msg = trim(msg)//adjustl(buffer)
414- do j = 2,size(a)
415- write (buffer,'(i0)') aa(j)
416- msg = trim(msg)//sep(:ls)//adjustl(buffer)
417- end do
418-
419- type is (integer(int16))
420-
421- write (buffer,'(i0)') aa(1)
422- msg = trim(msg)//adjustl(buffer)
423- do j = 2,size(a)
424- write (buffer,'(i0)') aa(j)
425- msg = trim(msg)//sep(:ls)//adjustl(buffer)
426- end do
427-
428- type is (integer(int32))
429-
430- write (buffer,'(i0)') aa(1)
431- msg = trim(msg)//adjustl(buffer)
432- do j = 2,size(a)
433- write (buffer,'(i0)') aa(j)
434- msg = trim(msg)//sep(:ls)//adjustl(buffer)
435- end do
436-
437- type is (integer(int64))
438-
439- write (buffer,'(i0)') aa(1)
440- msg = trim(msg)//adjustl(buffer)
441- do j = 2,size(a)
442- write (buffer,'(i0)') aa(j)
443- msg = trim(msg)//sep(:ls)//adjustl(buffer)
444- end do
445-
446- type is (real(real32))
447-
448- write (buffer,'(es15.8e2)') aa(1)
400+ !> Numeric types
401+ #:for k1, t1 in KINDS_TYPES
402+ type is (${t1}$)
403+ #:if 'real' in t1
404+ buffer_format = FMT_REAL_${k1}$
405+ #:elif 'complex' in t1
406+ buffer_format = FMT_COMPLEX_${k1}$
407+ #:else
408+ buffer_format = '(i0)'
409+ #:endif
410+ write (buffer,buffer_format) aa(1)
449411 msg = trim(msg)//adjustl(buffer)
450412 do j = 2,size(a)
451- write (buffer,'(es15.8e2)' ) aa(j)
413+ write (buffer,buffer_format ) aa(j)
452414 msg = trim(msg)//sep(:ls)//adjustl(buffer)
453415 end do
416+ msg = trim(msg)//sep(:ls)//trim(adjustl(buffer))
454417
455- type is (real(real64))
456-
457- write (buffer,'(es24.16e3)') aa(1)
458- msg = trim(msg)//adjustl(buffer)
459- do j = 2,size(a)
460- write (buffer,'(es24.16e3)') aa(j)
461- msg = trim(msg)//sep(:ls)//adjustl(buffer)
462- end do
463-
464- type is (real(real128))
465-
466- write (buffer,'(es44.35e4)') aa(1)
467- msg = trim(msg)//adjustl(buffer)
468- do j = 2,size(a)
469- write (buffer,'(es44.35e4)') aa(j)
470- msg = trim(msg)//sep(:ls)//adjustl(buffer)
471- end do
472-
473- type is (complex(real32))
474-
475- write (buffer,'(es15.8e2)') aa(1)%re
476- write (buffer2,'(es15.8e2)') aa(1)%im
477- msg = trim(msg)//'('//trim(adjustl(buffer))//','//trim(adjustl(buffer2))//')'
478- do j = 2,size(a)
479- write (buffer,'(es15.8e2)') aa(j)%re
480- write (buffer2,'(es15.8e2)') aa(j)%im
481- msg = trim(msg)//sep(:ls)//'('//trim(adjustl(buffer))//','//trim(adjustl(buffer2))//')'
482- end do
483-
484- type is (complex(real64))
485-
486- write (buffer,'(es24.16e3)') aa(1)%re
487- write (buffer2,'(es24.16e3)') aa(1)%im
488- msg = trim(msg)//'('//trim(adjustl(buffer))//','//trim(adjustl(buffer2))//')'
489- do j = 2,size(a)
490- write (buffer,'(es24.16e3)') aa(j)%re
491- write (buffer2,'(es24.16e3)') aa(j)%im
492- msg = trim(msg)//sep(:ls)//'('//trim(adjustl(buffer))//','//trim(adjustl(buffer2))//')'
493- end do
494-
495- type is (complex(real128))
496-
497- write (buffer,'(es44.35e4)') aa(1)%re
498- write (buffer2,'(es44.35e4)') aa(1)%im
499- msg = trim(msg)//'('//trim(adjustl(buffer))//','//trim(adjustl(buffer2))//')'
500- do j = 2,size(a)
501- write (buffer,'(es44.35e4)') aa(j)%re
502- write (buffer2,'(es44.35e4)') aa(j)%im
503- msg = trim(msg)//sep(:ls)//'('//trim(adjustl(buffer))//','//trim(adjustl(buffer2))//')'
504- end do
505-
418+ #:endfor
506419 class default
507-
508420 msg = trim(msg)//' <ERROR: INVALID TYPE>'
509421
510422 end select
0 commit comments