1 /*******************************************************************************
2 
3     Implementation of buffer which contains elements with no indirections
4     within them (== purely value types).
5 
6     Copyright:
7         Copyright (c) 2016 dunnhumby Germany GmbH.
8         All rights reserved.
9 
10     License:
11         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
12         Alternatively, this file may be distributed under the terms of the Tango
13         3-Clause BSD License (see LICENSE_BSD.txt for details).
14 
15 *******************************************************************************/
16 
17 module ocean.core.buffer.NoIndirections;
18 
19 template NoIndirectionsBufferImpl ( )
20 {
21     /***************************************************************************
22 
23         Plain D array internally used as buffer storage
24 
25     ***************************************************************************/
26 
27     private T[] data;
28 
29     /***************************************************************************
30 
31         Assigns data to stored data from other slice
32 
33         Params:
34             rhs   = slice to assign from
35 
36     ***************************************************************************/
37 
38     void opAssign ( in T[] rhs )
39     {
40         this.length = rhs.length;
41         this.data[] = rhs[];
42     }
43 
44     /***************************************************************************
45 
46         Assigns data to stored data from other slice
47 
48         Params:
49             rhs   = slice to assign from
50             begin = starting index for local data
51             end   = end index for local data
52 
53     ***************************************************************************/
54 
55     void opSliceAssign ( in T[] rhs, ptrdiff_t begin = 0,
56         ptrdiff_t end = -1 )
57     {
58         if (end < 0)
59             end = this.length();
60         this.data[begin .. end] = rhs[];
61     }
62 
63     /***************************************************************************
64 
65         Sets all elements of internal slice to rhs
66 
67         Params:
68             rhs   = value to assign from
69             begin = starting index for local data
70             end   = end index for local data
71 
72     ***************************************************************************/
73 
74     void opSliceAssign ( in T rhs, ptrdiff_t begin = 0,
75         ptrdiff_t end = -1 )
76     {
77         if (end < 0)
78             end = this.length();
79         this.data[begin .. end] = rhs;
80     }
81 
82     /***************************************************************************
83 
84         Individual element access.
85 
86         Params:
87             i = element index
88 
89         Returns:
90             Requested element itself or pointer to requested element for
91                 structs
92 
93     ***************************************************************************/
94 
95     T* opIndex ( size_t i )
96     {
97         return &this.data[i];
98     }
99 
100     /***************************************************************************
101 
102         Invidual element assignment
103 
104         Params:
105             value = new element value
106             i = element index
107 
108     ***************************************************************************/
109 
110     void opIndexAssign ( in T value, size_t i )
111     {
112         this.data[i] = value;
113     }
114 
115     /***************************************************************************
116 
117         Appends to current buffer
118 
119         Params:
120             op = operation to perform
121             rhs = array or element to append
122 
123     ***************************************************************************/
124 
125     void opOpAssign (string op : "~") ( in T rhs )
126     {
127         this.length = this.data.length + 1;
128         this.data[$-1] = rhs;
129     }
130 
131     /***************************************************************************
132 
133         ditto
134 
135     ***************************************************************************/
136 
137     void opOpAssign (string op : "~") ( in T[] rhs )
138     {
139         this.length = this.data.length + rhs.length;
140         this.data[$-rhs.length .. $] = rhs[];
141     }
142 
143     /***************************************************************************
144 
145         Buffer element iteration
146 
147         Params:
148             dg = foreach loop body
149 
150     ***************************************************************************/
151 
152     int opApply ( scope int delegate(ref const(T)) dg ) const
153     {
154         foreach (elem; this.data)
155         {
156             auto status = dg(elem);
157             if (status != 0)
158                 return status;
159         }
160 
161         return 0;
162     }
163 
164     /***************************************************************************
165 
166         Buffer element iteration (with index)
167 
168         Params:
169             dg = foreach loop body
170 
171     ***************************************************************************/
172 
173     int opApply ( scope int delegate(ref size_t, ref const(T)) dg ) const
174     {
175         foreach (index, elem; this.data)
176         {
177             auto status = dg(index, elem);
178             if (status != 0)
179                 return status;
180         }
181 
182         return 0;
183     }
184 }