1 /******************************************************************************* 2 3 Utility that resets value state in a way that its memory can be reused again 4 as much as possible. Resets arrays to 0 length and values to their init 5 state. 6 7 Copyright: 8 Copyright (c) 2018 dunnhumby Germany GmbH. 9 All rights reserved. 10 11 License: 12 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 13 Alternatively, this file may be distributed under the terms of the Tango 14 3-Clause BSD License (see LICENSE_BSD.txt for details). 15 16 *******************************************************************************/ 17 18 module ocean.meta.values.Reset; 19 20 import ocean.meta.types.Qualifiers; 21 22 import ocean.meta.values.VisitValue; 23 import ocean.meta.traits.Basic; 24 25 import ocean.core.Test; 26 27 /******************************************************************************* 28 29 Utility that resets value state in a way that its memory can be reused again 30 as much as possible. Resets arrays to 0 length and values to their init 31 state. 32 33 Non-class references are ignored. For classes it tries to recurse 34 into fields of the class instance without nullifying actual reference. 35 36 Params: 37 value = value to reset 38 39 *******************************************************************************/ 40 41 public void reset ( T ) ( ref T value ) 42 { 43 Reset visitor; 44 visitValue(value, visitor); 45 } 46 47 /// 48 unittest 49 { 50 // Can reset single value: 51 int x = 42; 52 reset(x); 53 test!("==")(x, 0); 54 55 // Or some array: 56 int[] arr = [ 1, 2, 3 ]; 57 reset(arr); 58 test!("==")(arr.length, 0); 59 test!("!=")(arr.ptr, null); 60 61 // Or some aggregate recursively: 62 struct S 63 { 64 int x; 65 mstring buf; 66 } 67 68 auto s = S(42, "abcd".dup); 69 reset(s); 70 test!("==")(s.x, 0); 71 test!("==")(s.buf.length, 0); 72 } 73 74 /// Visitor for ocean.meta.values.VisitValue 75 private struct Reset 76 { 77 // has to be public to be usable from VisitValue module 78 public bool visit ( T ) ( T* value ) 79 { 80 static if (isArrayType!(T) == ArrayKind.Dynamic) 81 { 82 (*value).length = 0; 83 assumeSafeAppend(*value); 84 } 85 else static if (isPrimitiveType!(T)) 86 { 87 *value = T.init; 88 } 89 90 return is(T == class) || !isReferenceType!(T); 91 } 92 }