@@ -10,6 +10,20 @@ const BUILTIN_TYPES = Set([Symbol, Type, UTF16String, BigFloat, BigInt])
10
10
const H5CONVERT_DEFINED = ObjectIdDict ()
11
11
const JLCONVERT_DEFINED = ObjectIdDict ()
12
12
13
+ if VERSION >= v " 0.4.0-dev+4319"
14
+ const EMPTY_TUPLE_TYPE = Tuple{}
15
+ typealias TypesType SimpleVector
16
+ typealias TupleType{T<: Tuple } Type{T}
17
+ tupletypes (T:: TupleType ) = T. parameters
18
+ typetuple (types) = Tuple{types... }
19
+ else
20
+ const EMPTY_TUPLE_TYPE = ()
21
+ typealias TypesType (Type... )
22
+ typealias TupleType (Type... )
23
+ tupletypes (T:: TupleType ) = T
24
+ typetuple (types) = tuple (types... )
25
+ end
26
+
13
27
# # Helper functions
14
28
15
29
# Holds information about the mapping between a Julia and HDF5 type
@@ -20,7 +34,7 @@ immutable JldTypeInfo
20
34
end
21
35
22
36
# Get information about the HDF5 types corresponding to Julia types
23
- function JldTypeInfo (parent:: JldFile , types:: (@compat Tuple{Vararg{Type}}) , commit:: Bool )
37
+ function JldTypeInfo (parent:: JldFile , types:: TypesType , commit:: Bool )
24
38
dtypes = Array (JldDatatype, length (types))
25
39
offsets = Array (Int, length (types))
26
40
offset = 0
@@ -257,7 +271,7 @@ function h5type{T<:Type}(parent::JldFile, ::Type{T}, commit::Bool)
257
271
id = HDF5. h5t_create (HDF5. H5T_COMPOUND, 8 )
258
272
HDF5. h5t_insert (id, " typename_" , 0 , h5fieldtype (parent, UTF8String, commit))
259
273
dtype = HDF5Datatype (id, parent. plain)
260
- commit ? commit_datatype (parent, dtype, Type) : JldDatatype (dtype, - 1 )
274
+ out = commit ? commit_datatype (parent, dtype, Type) : JldDatatype (dtype, - 1 )
261
275
end
262
276
263
277
gen_h5convert {T<:Type} (:: JldFile , :: Type{T} ) = nothing
@@ -292,16 +306,13 @@ h5fieldtype{T,N}(parent::JldFile, ::Type{Array{T,N}}, ::Bool) = JLD_REF_TYPE
292
306
# # Tuples
293
307
294
308
if INLINE_TUPLE
295
- h5fieldtype (parent:: JldFile , T:: (@compat Tuple{Vararg{Type}}) , commit:: Bool ) =
309
+ h5fieldtype (parent:: JldFile , T:: TupleType , commit:: Bool ) =
296
310
isleaftype (T) ? h5type (parent, T, commit) : JLD_REF_TYPE
297
311
else
298
- h5fieldtype (parent:: JldFile , T:: (@compat Tuple{Vararg{Type}}) , :: Bool ) = JLD_REF_TYPE
312
+ h5fieldtype (parent:: JldFile , T:: TupleType , :: Bool ) = JLD_REF_TYPE
299
313
end
300
314
301
- function h5type (parent:: JldFile , T:: (@compat Tuple{Vararg{Type}}) , commit:: Bool )
302
- ! isa (T, (@compat Tuple{Vararg{Union ((@compat Tuple), DataType)}})) && unknown_type_err (T)
303
- T = T:: (@compat Tuple{Vararg{Union((@compat Tuple) , DataType)}})
304
-
315
+ function h5type (parent:: JldFile , T:: TupleType , commit:: Bool )
305
316
haskey (parent. jlh5type, T) && return parent. jlh5type[T]
306
317
# Tuples should always be concretely typed, unless we're
307
318
# reconstructing a tuple, in which case commit will be false
@@ -321,7 +332,7 @@ function h5type(parent::JldFile, T::(@compat Tuple{Vararg{Type}}), commit::Bool)
321
332
dtype = HDF5Datatype (id, parent. plain)
322
333
if commit
323
334
jlddtype = commit_datatype (parent, dtype, T)
324
- if isempty (T)
335
+ if T == EMPTY_TUPLE_TYPE
325
336
# to allow recovery of empty tuples, which HDF5 does not allow
326
337
a_write (dtype, " empty" , @compat UInt8 (1 ))
327
338
end
@@ -331,21 +342,22 @@ function h5type(parent::JldFile, T::(@compat Tuple{Vararg{Type}}), commit::Bool)
331
342
end
332
343
end
333
344
334
- function gen_jlconvert (typeinfo:: JldTypeInfo , T:: (@compat Tuple{Vararg{Type}}) )
345
+ function gen_jlconvert (typeinfo:: JldTypeInfo , T:: TupleType )
335
346
haskey (JLCONVERT_DEFINED, T) && return
336
347
337
348
ex = Expr (:block )
338
349
args = ex. args
339
350
tup = Expr (:tuple )
340
351
tupargs = tup. args
352
+ types = tupletypes (T)
341
353
for i = 1 : length (typeinfo. dtypes)
342
354
h5offset = typeinfo. offsets[i]
343
355
field = symbol (string (" field" , i))
344
356
345
357
if HDF5. h5t_get_class (typeinfo. dtypes[i]) == HDF5. H5T_REFERENCE
346
358
push! (args, :($ field = read_ref (file, unsafe_load (convert (Ptr{HDF5ReferenceObj}, ptr)+ $ h5offset))))
347
359
else
348
- push! (args, :($ field = jlconvert ($ (T [i]), file, ptr+ $ h5offset)))
360
+ push! (args, :($ field = jlconvert ($ (types [i]), file, ptr+ $ h5offset)))
349
361
end
350
362
push! (tupargs, field)
351
363
end
@@ -434,7 +446,20 @@ function _gen_jlconvert_immutable(typeinfo::JldTypeInfo, T::ANY)
434
446
h5offset = typeinfo. offsets[i]
435
447
jloffset = jloffsets[i]
436
448
437
- if HDF5. h5t_get_class (typeinfo. dtypes[i]) == HDF5. H5T_REFERENCE
449
+ if isa (T. types[i], TupleType) && VERSION >= v " 0.4.0-dev+4319" && T. types[i]. pointerfree
450
+ # We continue to store tuples as references for the sake of
451
+ # backwards compatibility, but on 0.4 they are now stored
452
+ # inline
453
+ push! (args, quote
454
+ ref = unsafe_load (convert (Ptr{HDF5ReferenceObj}, ptr)+ $ h5offset)
455
+ if ref == HDF5. HDF5ReferenceObj_NULL
456
+ warn (""" A pointerfree tuple field was undefined.
457
+ This is not supported in Julia 0.4 and the corresponding tuple will be uninitialized.""" )
458
+ else
459
+ unsafe_store! (convert (Ptr{$ (T. types[i])}, out)+ $ jloffset, read_ref (file, ref))
460
+ end
461
+ end )
462
+ elseif HDF5. h5t_get_class (typeinfo. dtypes[i]) == HDF5. H5T_REFERENCE
438
463
obj = gensym (" obj" )
439
464
push! (args, quote
440
465
ref = unsafe_load (convert (Ptr{HDF5ReferenceObj}, ptr)+ $ h5offset)
@@ -523,19 +548,20 @@ end
523
548
# # Common functions for all non-special types (including gen_h5convert)
524
549
525
550
# Whether this datatype should be stored as opaque
526
- isopaque (t: :@compat Tuple{Vararg{Type}}) = isa (t, ())
527
- isopaque (t:: DataType ) = isempty (fieldnames (t))
551
+ isopaque (t:: TupleType ) = t == EMPTY_TUPLE_TYPE
552
+ # isopaque(t::DataType) = isempty(fieldnames(t))
553
+ isopaque (t:: DataType ) = isa (t, TupleType) ? t == EMPTY_TUPLE_TYPE : isempty (fieldnames (t))
528
554
529
555
# The size of this datatype in the HDF5 file (if opaque)
530
- opaquesize (t: :@compat Tuple{Vararg{DataType}} ) = 1
556
+ opaquesize (t:: TupleType ) = 1
531
557
opaquesize (t:: DataType ) = max (1 , t. size)
532
558
533
559
# Whether a type that is stored inline in HDF5 should be stored as a
534
560
# reference in Julia. This will only be called such that it returns
535
561
# true for some unions of special types defined above, unless either
536
562
# INLINE_TUPLE or INLINE_POINTER_IMMUTABLE is true.
537
563
uses_reference (T:: DataType ) = ! T. pointerfree
538
- uses_reference (:: @compat Tuple ) = true
564
+ uses_reference (:: TupleType ) = true
539
565
uses_reference (:: UnionType ) = true
540
566
541
567
unknown_type_err (T) =
@@ -548,19 +574,21 @@ gen_h5convert(parent::JldFile, T) =
548
574
# There is no point in specializing this
549
575
function _gen_h5convert (parent:: JldFile , T:: ANY )
550
576
dtype = parent. jlh5type[T]. dtype
551
- istuple = isa (T, @compat Tuple)
577
+ istuple = isa (T, TupleType)
578
+
579
+ if isopaque (T)
580
+ if T. size == 0
581
+ @eval h5convert! (out:: Ptr , :: JldFile , x:: $T , :: JldWriteSession ) = nothing
582
+ else
583
+ @eval h5convert! (out:: Ptr , :: JldFile , x:: $T , :: JldWriteSession ) =
584
+ unsafe_store! (convert (Ptr{$ T}, out), x)
585
+ end
586
+ return
587
+ end
588
+
552
589
if istuple
553
- types = T
590
+ types = tupletypes (T)
554
591
else
555
- if isopaque (T:: DataType )
556
- if (T:: DataType ). size == 0
557
- @eval h5convert! (out:: Ptr , :: JldFile , x:: $T , :: JldWriteSession ) = nothing
558
- else
559
- @eval h5convert! (out:: Ptr , :: JldFile , x:: $T , :: JldWriteSession ) =
560
- unsafe_store! (convert (Ptr{$ T}, out), x)
561
- end
562
- return
563
- end
564
592
types = (T:: DataType ). types
565
593
end
566
594
@@ -704,9 +732,9 @@ function reconstruct_type(parent::JldFile, dtype::HDF5Datatype, savedname::Abstr
704
732
end
705
733
end
706
734
707
- if startswith (savedname, " (" )
735
+ if startswith (savedname, " (" ) || startswith (savedname, " Core.Tuple{ " )
708
736
# We're reconstructing a tuple
709
- tuple (fieldtypes... )
737
+ typetuple (fieldtypes)
710
738
else
711
739
# We're reconstructing some other type
712
740
@eval begin
0 commit comments