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