00001 // Copyright (C) 2007 EPITA Research and Development Laboratory 00002 // 00003 // This file is part of the Milena Library. This library is free 00004 // software; you can redistribute it and/or modify it under the terms 00005 // of the GNU General Public License version 2 as published by the 00006 // Free Software Foundation. 00007 // 00008 // This library is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 // General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this library; see the file COPYING. If not, write to 00015 // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 00016 // Boston, MA 02111-1307, USA. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software library without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to 00022 // produce an executable, this file does not by itself cause the 00023 // resulting executable to be covered by the GNU General Public 00024 // License. This exception does not however invalidate any other 00025 // reasons why the executable file might be covered by the GNU General 00026 // Public License. 00027 00028 // File: tour1_extra.cc. 00029 00030 #include <oln/core/1d/image1d.hh> 00031 #include <oln/arith/plus.hh> 00032 #include <oln/debug/println.hh> 00033 00034 00035 00036 int main() 00037 { 00038 using namespace oln; 00039 00040 00041 // Let us take a few examples to illustrate how images and data are 00042 // managed. In these examples, we will use the notion of "block of 00043 // instructions" from the C/C++ languages: "{" ... "}". 00044 00045 00046 00047 00048 // Example 1: 00049 00050 { // A new block starts here. 00051 00052 image1d<float> local_ima(1000); 00053 // A non-empty image is created; a memory buffer is automatically 00054 // allocated to store image data. Some code using 'local_ima' can 00055 // be inserted here... 00056 00057 } // The block ends and 'local_ima' is not more accessible. 00058 00059 // At the end of the block, since the user cannot use 'local_ima' 00060 // anymore, the memory is automatically deallocated. 00061 00062 00063 00064 00065 // Example 2: 00066 00067 image1d<float> ima; // An empty image---a variable. 00068 00069 { // A new block. 00070 00071 image1d<float> local_ima(1000); // A non-empty image. 00072 // Some work is performed with 'local_ima' here. 00073 // ... 00074 ima = local_ima; // Last, we state that ima IS local_ima. 00075 00076 } // End of the block: 'local_ima' is no more accessible. 00077 00078 assert(not ima.is_empty()); // We test that 'ima' is no more empty. 00079 00080 // Since we state that "ima IS local_ima" and since 'ima' is still 00081 // accessible by the user, the contents of 'local_ima' is preserved. 00082 00083 // Conversely to the example 1, the memory allocated for 'local_ima' 00084 // is thus NOT deallocated: the data of 'local_ima' is "transfered" 00085 // to 'ima'. There is NO data "copy" involved during this transfer 00086 // so it is fast and it saves memory. 00087 00088 00089 00090 00091 // Example 3: 00092 00093 { 00094 image1d<int> orig(5); // An original image. 00095 for (int i = 0; i < 5; ++i) 00096 orig.at(i) = i; 00097 debug::println(orig); 00098 // 0 1 2 3 4 00099 00100 image1d<int> ima = orig; // 'ima' is 'orig'. 00101 ima = ima + ima; // Point-wise sum of ima and itself. 00102 debug::println(ima); 00103 // 0 2 4 6 8 00104 00105 debug::println(orig); 00106 // 0 1 2 3 4 00107 } 00108 00109 // To explain this result, let us detail the point-wise sum line. 00110 // The assignment "ima = ima + ima" is a two-step process: first 00111 // "ima + ima" is computed, then the assignment is performed. This 00112 // line can be rewritten as: 00113 00114 // image1d<int> anon = ima + ima; // line (a) 00115 // ima = anon; // line (b) 00116 00117 // where 'anon' is the "anonymous" result of the sum. We can see 00118 // that 'ima' is used in line (a) to compute a new image, namely 00119 // 'anon'. At that precise line, 'ima' still designates 'orig'. At 00120 // line (b) the definition of 'ima' changes: 'ima' was designating 00121 // 'orig', now it designates 'anon', that is, the sum result. 00122 // Eventually the data of 'orig' have never changed since it has 00123 // been initialized. 00124 00125 // In this example, two images with effective data have been 00126 // created: the sum result, which is accessible through 'ima', and 00127 // 'orig'. 00128 00129 // The same explanation in pictures. When the sum "ima + ima" is 00130 // computed, the images and their data look like: 00131 // 00132 // +-----------+ 00133 // orig --> | 0 1 2 3 4 | 00134 // +-----------+ 00135 // ^ 00136 // ima ______| 00137 // 00138 // +-----------+ 00139 // anon --> | 0 2 4 6 8 | 00140 // +-----------+ 00141 // 00142 // Then the assignment modifies this scheme into: 00143 // 00144 // +-----------+ 00145 // orig --> | 0 1 2 3 4 | 00146 // +-----------+ 00147 // ima ______ 00148 // | 00149 // v 00150 // +-----------+ 00151 // anon --> | 0 2 4 6 8 | 00152 // +-----------+ 00153 // 00154 // and the temporary 'anon' disappears. 00155 00156 00157 00158 00159 00160 // Example 4: 00161 00162 { 00163 image1d<int> ima(5); 00164 for (int i = 0; i < 5; ++i) 00165 ima.at(i) = i; 00166 debug::println(ima); 00167 // 0 1 2 3 4 00168 00169 ima = ima + ima; 00170 debug::println(ima); 00171 // 0 2 4 6 8 00172 } 00173 00174 // Let us re-write the assignment line: 00175 00176 // image1d<int> anon = ima + ima; // line (a) 00177 // ima = anon; // line (b) 00178 00179 // A new image, 'anon', is created to store the sum result; this 00180 // image is just like a temporary object since it is anonymous. In 00181 // line (a) the definition of 'ima' changes: it was the original 00182 // image with its data being "0 1 2 3 4" and it now designates the 00183 // sum result. The original data becomes inaccessible by the user 00184 // so it is automatically deallocated. 00185 00186 // The same explanation In pictures. After the sum is computed, we 00187 // have: 00188 // +-----------+ 00189 // ima ---> | 0 1 2 3 4 | 00190 // +-----------+ 00191 // 00192 // +-----------+ 00193 // anon --> | 0 2 4 6 8 | 00194 // +-----------+ 00195 // 00196 // and the assignment of 'ima' leads to: 00197 // 00198 // +-----------+ 00199 // ima | 0 1 2 3 4 | 00200 // | +-----------+ 00201 // |_________ 00202 // | 00203 // v 00204 // +-----------+ 00205 // anon --> | 0 2 4 6 8 | 00206 // +-----------+ 00207 // 00208 // so the original data, unreachable, are deallocated and the 00209 // temporary 'anon' disappears; we end up with: 00210 // 00211 // +-----------+ 00212 // ima ---> | 0 2 4 6 8 | 00213 // +-----------+ 00214 }