sample/subextension/main.cpp

00001 /*
00002 
00003 Copyright (c) 2002-2005, Yauheni Akhotnikau
00004 All rights reserved.
00005 
00006 Redistribution and use in source and binary forms, with or without
00007 modification, are permitted provided that the following conditions are met:
00008 
00009 - Redistributions of source code must retain the above copyright notice, this
00010 list of conditions and the following disclaimer.
00011 
00012 - Redistributions in binary form must reproduce the above copyright notice, this
00013 list of conditions and the following disclaimer in the documentation and/or
00014 other materials provided with the distribution.
00015 
00016 - The name of the author may not be used to endorse or promote products derived
00017 from this software without specific prior written permission.
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00020 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00021 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
00022 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00024 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00027 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00028 OF SUCH DAMAGE.
00029 
00030 */
00031 
00032 /*
00033   Пример работы с механизмом subclassing by extension.
00034 
00035   В качестве политики для умных указателей используется
00036   политика на основе клонирования.
00037 */
00038 
00039 #include <iostream>
00040 #include <stdexcept>
00041 #include <memory>
00042 
00043 #include <oess_1/io/h/mem_buf.hpp>
00044 #include <oess_1/stdsn/h/serializable.hpp>
00045 #include <oess_1/stdsn/h/ent_std.hpp>
00046 #include <oess_1/stdsn/h/inout_templ.hpp>
00047 #include <oess_1/stdsn/h/shptr.hpp>
00048 
00049 /*
00050   Базовый класс в иерархии subclassing by extension классов.
00051 */
00052 class base_t
00053   : public oess_1::stdsn::serializable_t
00054   {
00055     OESS_SERIALIZER( base_t )
00056   public :
00057     base_t() {}
00058     virtual ~base_t()
00059       {}
00060 
00061     virtual base_t *
00062     clone() const = 0;
00063   };
00064 
00065 class base_shptr_t
00066   : public oess_1::stdsn::shptr_skeleton_t<
00067         base_t,
00068         oess_1::stdsn::cloneable_policy_t< base_t > >
00069   {
00070     typedef oess_1::stdsn::shptr_skeleton_t<
00071             base_t,
00072             oess_1::stdsn::cloneable_policy_t< base_t > >
00073         base_type_t;
00074 
00075     OESS_SERIALIZER( base_shptr_t )
00076     OESS_1_SHPTR_IFACE(
00077         base_shptr_t,
00078         base_t,
00079         base_type_t )
00080   };
00081 
00082 /*
00083   Класс, атрибутами которого являются экземпляры класса base_t.
00084 */
00085 class holder_t
00086   : public oess_1::stdsn::serializable_t
00087   {
00088     OESS_SERIALIZER( holder_t )
00089   public :
00090     holder_t() {}
00091     holder_t(
00092       const base_shptr_t & value )
00093       : m_value( value )
00094       {}
00095     virtual ~holder_t() {}
00096 
00097     const base_shptr_t &
00098     value() const
00099       {
00100         return m_value;
00101       }
00102 
00103     void
00104     set_value( const base_shptr_t & v )
00105       {
00106         m_value = v;
00107       }
00108 
00109   private :
00110     base_shptr_t  m_value;
00111   };
00112 
00113 /*
00114   Первый потомок base_t.
00115 */
00116 class string_value_t
00117   : public base_t
00118   {
00119     typedef base_t base_type_t;
00120     OESS_SERIALIZER( string_value_t )
00121   public :
00122     string_value_t()
00123       {}
00124     string_value_t( const std::string & value )
00125       : m_value( value )
00126       {}
00127     virtual ~string_value_t()
00128       {}
00129 
00130     virtual base_t *
00131     clone() const
00132       {
00133         return new string_value_t( *this );
00134       }
00135 
00136     const std::string &
00137     value() const
00138       {
00139         return m_value;
00140       }
00141 
00142     void
00143     set_value( const std::string & v )
00144       {
00145         m_value = v;
00146       }
00147 
00148   private :
00149     std::string m_value;
00150   };
00151 
00152 /*
00153   Второй потомок base_t.
00154 */
00155 class incapsulated_value_t
00156   : public base_t
00157   {
00158     typedef base_t base_type_t;
00159     OESS_SERIALIZER( incapsulated_value_t )
00160   public :
00161     incapsulated_value_t()
00162       {
00163       }
00164     incapsulated_value_t(
00165       const base_shptr_t & original,
00166       const std::string & self )
00167       : m_original( original )
00168       , m_self( self )
00169       {
00170       }
00171     virtual ~incapsulated_value_t()
00172       {
00173       }
00174 
00175     virtual base_t *
00176     clone() const
00177       {
00178         return new incapsulated_value_t( *this );
00179       }
00180 
00181     const base_shptr_t &
00182     original() const
00183       {
00184         return m_original;
00185       }
00186 
00187     void
00188     set_original(
00189       const base_shptr_t & o )
00190       {
00191         m_original = o;
00192       }
00193 
00194     const std::string &
00195     self() const
00196       {
00197         return m_self;
00198       }
00199 
00200     void
00201     set_self( const std::string & v )
00202       {
00203         m_self = v;
00204       }
00205 
00206   private :
00207     base_shptr_t  m_original;
00208     std::string m_self;
00209   };
00210 
00211 #include "main.ddl.cpp"
00212 
00213 const std::string test_identity = "my-test-identification-string";
00214 
00215 void
00216 receive_string_value(
00217   const holder_t & holder )
00218   {
00219     const string_value_t & sv = *holder.value().cast_to(
00220         oess_1::stdsn::shptr_type_tag< string_value_t >() );
00221 
00222     if( test_identity != sv.value() )
00223       throw std::domain_error(
00224           std::string( "receive_string_value: Expected value: " ) +
00225           test_identity + ", actual value: " + sv.value() );
00226   }
00227 
00228 void
00229 receive_incapsulated_string_value(
00230   const holder_t & holder )
00231   {
00232     const incapsulated_value_t & iv = *holder.value().cast_to(
00233         oess_1::stdsn::shptr_type_tag< incapsulated_value_t  >() );
00234 
00235     if( test_identity != iv.self() )
00236       throw std::domain_error(
00237           std::string( "receive_incapsulated_string_value: "
00238               "Expected 'self' value: " ) +
00239           test_identity + ", actual 'self' value: " + iv.self() );
00240 
00241     const string_value_t & sv = *iv.original().cast_to(
00242         oess_1::stdsn::shptr_type_tag< string_value_t >() );
00243     if( test_identity != sv.value() )
00244       throw std::domain_error(
00245           std::string( "receive_incapsulated_string_value: "
00246               "Expected 'string' value: " ) +
00247           test_identity + ", actual 'string' value: " + sv.value() );
00248   }
00249 
00250 holder_t
00251 send_string_value(
00252   const string_value_t & v )
00253   {
00254     return holder_t( base_shptr_t( v.clone() ) );
00255   }
00256 
00257 holder_t
00258 send_incapsulated_value(
00259   const base_shptr_t & original,
00260   const std::string & self )
00261   {
00262     return holder_t(
00263         base_shptr_t(
00264             new incapsulated_value_t( original, self ) ) );
00265   }
00266 
00267 void
00268 test_string_value_packing()
00269   {
00270     // Эта строка не должна вызвать исключения.
00271     receive_string_value(
00272         send_string_value(
00273             string_value_t( test_identity ) ) );
00274   }
00275 
00276 void
00277 test_incapsulated_value_packing()
00278   {
00279     // Эта строка не должна вызвать исключения.
00280     receive_incapsulated_string_value(
00281         send_incapsulated_value(
00282             base_shptr_t( new string_value_t( test_identity ) ),
00283             test_identity ) );
00284 
00285     bool is_test_failed = true;
00286     try
00287       {
00288         // А вот здесь исключение должно произойти.
00289         receive_incapsulated_string_value(
00290             send_incapsulated_value(
00291                 base_shptr_t(
00292                     new incapsulated_value_t(
00293                         base_shptr_t(
00294                             new string_value_t(
00295                                 test_identity ) ),
00296                         test_identity ) ),
00297                 test_identity ) );
00298       }
00299     catch( const oess_1::ex_t & )
00300       {
00301         is_test_failed = false;
00302       }
00303     if( is_test_failed )
00304       throw std::logic_error(
00305           "Exception for invalid casting not thrown!" );
00306   }
00307 
00308 int
00309 main()
00310   {
00311     try
00312       {
00313         test_string_value_packing();
00314         test_incapsulated_value_packing();
00315 
00316         return 0;
00317       }
00318     catch( const std::exception & x )
00319       {
00320         std::cerr << "### " << x.what() << " ###" << std::endl;
00321       }
00322 
00323     return 2;
00324   }
00325 

Документация по ObjESSty. Последние изменения: Fri Oct 13 18:35:35 2006. Создано системой  doxygen 1.4.7
Hosted by uCoz