Skip to content

Commit cc823d9

Browse files
authored
Merge pull request #70 from sourceryinstitute/string-features
String features: unary array operator(.cat.) and constructor from `real` scalar
2 parents de6a957 + c063898 commit cc823d9

File tree

4 files changed

+61
-11
lines changed

4 files changed

+61
-11
lines changed

src/sourcery/sourcery_string_m.f90

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module sourcery_string_m
55
private
66
public :: string_t
77
public :: array_of_strings
8+
public :: operator(.cat.) ! element-wise concatenation operator
89

910
type, extends(characterizable_t) :: string_t
1011
private
@@ -46,10 +47,25 @@ elemental module function from_default_integer(i) result(string)
4647
type(string_t) string
4748
end function
4849

50+
elemental module function from_real(x) result(string)
51+
implicit none
52+
real, intent(in) :: x
53+
type(string_t) string
54+
end function
55+
4956
end interface
5057

51-
interface
58+
interface operator(.cat.)
5259

60+
pure module function concatenate_elements(strings) result(concatenated_strings)
61+
implicit none
62+
type(string_t), intent(in) :: strings(:)
63+
type(string_t) concatenated_strings
64+
end function
65+
66+
end interface
67+
68+
interface
5369
pure module function as_character(self) result(raw_string)
5470
implicit none
5571
class(string_t), intent(in) :: self

src/sourcery/sourcery_string_s.f90

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@
2424
string = string_t(characters)
2525
end procedure
2626

27+
module procedure from_real
28+
integer, parameter :: sign_ = 1, decimal_ = 1, digits = precision(x) + 3, exponent_width = 4
29+
character(len=sign_ + decimal_ + digits + exponent_width) characters
30+
write(characters, '(g0)') x
31+
string = string_t(characters)
32+
end procedure
33+
34+
module procedure concatenate_elements
35+
integer s
36+
37+
!allocate(concatenated_strings(sum(len(strings%string()))))
38+
39+
concatenated_strings = ""
40+
do s = 1, size(strings)
41+
concatenated_strings = concatenated_strings // strings(s)%string()
42+
end do
43+
end procedure
44+
2745
module procedure array_of_strings
2846
character(len=:), allocatable :: remainder, next_string
2947
integer next_delimiter, string_end

src/sourcery_m.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module sourcery_m
55
use sourcery_bin_m, only : bin_t
66
use sourcery_formats_m, only : csv, cscv, separated_values
77
use sourcery_file_m, only : file_t
8-
use sourcery_string_m, only : string_t
8+
use sourcery_string_m, only : string_t, operator(.cat.)
99
use sourcery_test_result_m, only : test_result_t
1010
use sourcery_test_m, only : test_t
1111
use sourcery_user_defined_collectives_m, only : co_all

test/string_test.f90

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module string_test_m
2-
use sourcery_m, only : test_t, test_result_t, string_t
2+
use sourcery_m, only : test_t, test_result_t, string_t, operator(.cat.)
33
implicit none
44

55
private
@@ -23,20 +23,22 @@ function results() result(test_results)
2323

2424
test_results = [ &
2525
test_result_t("is_allocated() result .true. if & only if the string_t component(s) is/are allocated", check_allocation()), &
26+
test_result_t('supporting operator(==) for string_t and character operands', supports_equivalence_operator()), &
27+
test_result_t('supporting operator(/=) for string_t and character operands', supports_non_equivalence_operator()), &
28+
test_result_t('supporting operator(//) for string_t and character operands', supports_concatenation_operator()), &
29+
test_result_t('assigning a string_t object to a character variable', assigns_string_t_to_character()), &
30+
test_result_t('assigning a character variable to a string_t object', assigns_character_to_string_t()), &
31+
test_result_t('constructing from a default integer', constructs_from_default_integer()), &
32+
test_result_t('constructing from a real value', constructs_from_real()), &
33+
test_result_t('supporting unary operator(.cat.) for array arguments', concatenates_elements()), &
2634
test_result_t("extracting a key string from a colon-separated key/value pair", extracts_key()), &
2735
test_result_t("extracting a real value from a colon-separated key/value pair", extracts_real_value()), &
2836
test_result_t("extracting a string value from a colon-separated key/value pair", extracts_string_value()), &
2937
test_result_t("extracting a logical value from a colon-separated key/value pair", extracts_logical_value()), &
3038
test_result_t("extracting an integer array value from a colon-separated key/value pair", extracts_integer_array_value()), &
3139
test_result_t("extracting an integer value from a colon-separated key/value pair", extracts_integer_value()), &
32-
test_result_t('supporting operator(==) for string_t and character operands', supports_equivalence_operator()), &
33-
test_result_t('supporting operator(/=) for string_t and character operands', supports_non_equivalence_operator()), &
34-
test_result_t('assigning a string_t object to a character variable', assigns_string_t_to_character()), &
35-
test_result_t('assigning a character variable to a string_t object', assigns_character_to_string_t()), &
36-
test_result_t('supporting operator(//) for string_t and character operands', supports_concatenation_operator()), &
37-
test_result_t('constructing from a default integer', constructs_from_default_integer()), &
38-
test_result_t('extracting file base name', extracts_file_base_name()), &
39-
test_result_t('extracting file name extension', extracts_file_name_extension()) &
40+
test_result_t('extracting a file base name', extracts_file_base_name()), &
41+
test_result_t('extracting a file name extension', extracts_file_name_extension()) &
4042
]
4143
end function
4244

@@ -160,6 +162,13 @@ function constructs_from_default_integer() result(passed)
160162
end associate
161163
end function
162164

165+
function constructs_from_real() result(passed)
166+
logical passed
167+
associate(string => string_t(123456789E+09))
168+
passed = adjustl(trim(string%string())) == "0.123456791E+18"
169+
end associate
170+
end function
171+
163172
function extracts_file_base_name() result(passed)
164173
logical passed
165174
associate(string => string_t(" foo .bar.too "))
@@ -174,4 +183,11 @@ function extracts_file_name_extension() result(passed)
174183
end associate
175184
end function
176185

186+
function concatenates_elements() result(passed)
187+
logical passed
188+
associate(elements => [string_t("foo"), string_t("bar")])
189+
passed = .cat. elements == "foobar"
190+
end associate
191+
end function
192+
177193
end module string_test_m

0 commit comments

Comments
 (0)