1 /*******************************************************************************
2 
3     Implementation of buffer which contains elements with indirections
4     within them. Such elements can't be implicitly converted between const
5     and mutable and thus API must be conservatively mutable.
6 
7     Copyright:
8         Copyright (c) 2016 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.core.buffer.WithIndirections;
19 
20 template WithIndirectionsBufferImpl ( )
21 {
22     /***************************************************************************
23 
24         Plain D array internally used as buffer storage
25 
26     ***************************************************************************/
27 
28     private T[] data;
29 
30     /***************************************************************************
31 
32         Assigns data to stored data from other slice
33 
34         Params:
35             rhs   = slice to assign from
36 
37     ***************************************************************************/
38 
39     void opAssign ( T[] rhs )
40     {
41         this.length = rhs.length;
42         this.data[] = rhs[];
43     }
44 
45     /***************************************************************************
46 
47         Assigns data to stored data from other slice
48 
49         Params:
50             rhs   = slice to assign from
51             begin = starting index for local data
52             end   = end index for local data
53 
54     ***************************************************************************/
55 
56     void opSliceAssign ( U ) ( U[] rhs, ptrdiff_t begin = 0,
57         ptrdiff_t end = -1 )
58     {
59         if (end < 0)
60             end = this.length();
61         this.data[begin .. end] = rhs[];
62     }
63 
64     /***************************************************************************
65 
66         Individual element access.
67 
68         Params:
69             i = element index
70 
71         Returns:
72             Pointer to requested element
73 
74     ***************************************************************************/
75 
76     T* opIndex ( size_t i )
77     {
78         return &this.data[i];
79     }
80 
81     /***************************************************************************
82 
83         Invidual element assignment
84 
85         Params:
86             value = new element value
87             i = element index
88 
89     ***************************************************************************/
90 
91     void opIndexAssign ( T value, size_t i )
92     {
93         this.data[i] = value;
94     }
95 
96     /***************************************************************************
97 
98         Appends to current buffer
99 
100         Params:
101             rhs = array or element to append
102 
103     ***************************************************************************/
104 
105     void opCatAssign ( T rhs )
106     {
107         this.length = this.data.length + 1;
108         this.data[$-1] = rhs;
109     }
110 
111     /***************************************************************************
112 
113         ditto
114 
115     ***************************************************************************/
116 
117     void opCatAssign ( T[] rhs )
118     {
119         this.length = this.data.length + rhs.length;
120         this.data[$-rhs.length .. $] = rhs[];
121     }
122 
123     /***************************************************************************
124 
125         Buffer element iteration
126 
127         Params:
128             dg = foreach loop body
129 
130     ***************************************************************************/
131 
132     int opApply ( scope int delegate(ref T) dg )
133     {
134         foreach (elem; this.data)
135         {
136             auto status = dg(elem);
137             if (status != 0)
138                 return status;
139         }
140 
141         return 0;
142     }
143 
144     /***************************************************************************
145 
146         Buffer element iteration (with index)
147 
148         Params:
149             dg = foreach loop body
150 
151     ***************************************************************************/
152 
153     int opApply ( scope int delegate(ref size_t, ref T) dg )
154     {
155         foreach (index, elem; this.data)
156         {
157             auto status = dg(index, elem);
158             if (status != 0)
159                 return status;
160         }
161 
162         return 0;
163     }
164 }