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             rhs = array or element to append
121 
122     ***************************************************************************/
123 
124     void opCatAssign ( in T rhs )
125     {
126         this.length = this.data.length + 1;
127         this.data[$-1] = rhs;
128     }
129 
130     /***************************************************************************
131 
132         ditto
133 
134     ***************************************************************************/
135 
136     void opCatAssign ( in T[] rhs )
137     {
138         this.length = this.data.length + rhs.length;
139         this.data[$-rhs.length .. $] = rhs[];
140     }
141 
142     /***************************************************************************
143 
144         Buffer element iteration
145 
146         Params:
147             dg = foreach loop body
148 
149     ***************************************************************************/
150 
151     int opApply ( scope int delegate(ref Const!(T)) dg ) const
152     {
153         foreach (elem; this.data)
154         {
155             auto status = dg(elem);
156             if (status != 0)
157                 return status;
158         }
159 
160         return 0;
161     }
162 
163     /***************************************************************************
164 
165         Buffer element iteration (with index)
166 
167         Params:
168             dg = foreach loop body
169 
170     ***************************************************************************/
171 
172     int opApply ( scope int delegate(ref size_t, ref Const!(T)) dg ) const
173     {
174         foreach (index, elem; this.data)
175         {
176             auto status = dg(index, elem);
177             if (status != 0)
178                 return status;
179         }
180 
181         return 0;
182     }
183 }