Changeset cda275f in git


Ignore:
Timestamp:
Sep 5, 2012, 3:25:07 PM (10 years ago)
Author:
Alexander Dreyer <alexander.dreyer@…>
Branches:
(u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'ad2543eab51733612ba7d118afc77edca719600e')
Children:
88180dcbe2ead266f3547e207fd8b7d03a0b9f1e
Parents:
e318c0df53d14d067ee1ee383417566c2e226e9b
git-author:
Alexander Dreyer <alexander.dreyer@itwm.fraunhofer.de>2012-09-05 15:25:07+02:00
git-committer:
Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-09-05 15:52:17+02:00
Message:
Added serialization

chg: clean up
Location:
Singular
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • Singular/countedref.cc

    re318c0 rcda275f  
    1 /// -*- c++ -*-
     1// -*- c++ -*-
    22//*****************************************************************************
    33/** @file countedref.cc
     
    1717
    1818
    19 
    20 #include <Singular/mod2.h>
    21 
    22 #include <Singular/ipid.h>
    23 #include <Singular/blackbox.h>
    24 #include <Singular/newstruct.h>
    25 
    26 #include <omalloc/omalloc.h>
    27 #include <kernel/febase.h>
    28 #include <kernel/longrat.h>
    29 #include <Singular/subexpr.h>
    30 #include <Singular/ipshell.h>
    31 
    32 #include "lists.h"
    33 #include "attrib.h"
     19#include "mod2.h"
     20#include "ipid.h"
    3421
    3522#include "countedref.h"
    3623
    37 #if 0
    38 /** @class CountedRefPtr
    39  * This class implements a smart pointer which handles pointer-style access
    40  * to a reference-counted structure and destructing the latter after use.
    41  *
    42  * The template arguments, include the pointer type @c PtrType, and two
    43  * integral (bool) properties: use @c isWeak to disallow destruction
    44  * and @c NeverNull to assume, that @c PtrType cannot be @c NULL.
    45  * Finally, @c CountType allows you to select a typ to represent the internal reference count.
    46  *
    47  * @note The class of @c PtrType must have an accessible integral attribute @c ref.
    48  * For convenience use @c RefCounter as public base.
    49  * In addition you must overload @c void CountedRefPtr_kill(PtrType) accordingly.
    50  **/
    51 template <class PtrType, bool isWeak = false, bool NeverNull = false, class CountType = short>
    52 class CountedRefPtr {
    53   typedef CountedRefPtr self;
    54 
    55 public:
    56   //{ @name Name template arguments
    57   typedef PtrType ptr_type;
    58   typedef CountType count_type;
    59   enum { is_weak = isWeak, never_null = NeverNull };
    60   //}
    61 
    62   /// Default constructor @note: exisis only if @c NeverNull is false
    63   CountedRefPtr(): m_ptr(NULL) {}
    64 
    65   /// Convert from pointer
    66   CountedRefPtr(ptr_type ptr): m_ptr(ptr) { reclaim(); }
    67 
    68   /// Convert from compatible smart pointer
    69   template <bool Never>
    70   CountedRefPtr(const CountedRefPtr<ptr_type, !is_weak, Never, count_type>& rhs):
    71     m_ptr(rhs.m_ptr) { reclaim(); }
    72 
    73   /// Construct refernce copy
    74   CountedRefPtr(const self& rhs):
    75     m_ptr(rhs.m_ptr) { reclaim(); }
    76 
    77   /// Unlink one reference
    78   ~CountedRefPtr() { release(); }
    79 
    80   //{ @name Replace data behind reference
    81   self& operator=(const self& rhs) { return operator=(rhs.m_ptr); }
    82   self& operator=(ptr_type ptr) {
    83     release();
    84     m_ptr = ptr;
    85     reclaim();
    86     return *this;
    87   }
    88   //}
    89 
    90   /// Checking equality
    91   bool operator==(const self& rhs) const { return m_ptr == rhs.m_ptr; }
    92 
    93   //{ @name Pointer-style interface
    94   bool operator==(ptr_type ptr) const { return m_ptr == ptr; }
    95   operator bool() const { return NeverNull || m_ptr; }
    96   operator const ptr_type() const { return m_ptr; }
    97   operator ptr_type() { return m_ptr; }
    98   const ptr_type operator->() const { return *this; }
    99   ptr_type operator->() { return *this; }
    100   //}
    101 
    102   //{ @name Reference count interface
    103   count_type count() const { return (*this? m_ptr->ref: 0); }
    104   void reclaim() { if (*this) ++m_ptr->ref; }
    105   void release() {
    106     if (*this && (--m_ptr->ref <= 0) && !is_weak)
    107       CountedRefPtr_kill(m_ptr);
    108   }
    109   //}
    110 
    111 private:
    112   /// Store actual pointer
    113   ptr_type m_ptr;
    114 };
    115 
    116 /// Default constructor only implemented if @c NeverNull is false
    117 //template <class PtrType, bool isWeak,bool val,class CountType>
    118 //inline CountedRefPtr<PtrType, isWeak, val, CountType>::CountedRefPtr():
    119 //  m_ptr(NULL) { }
    120 
    121 /** @class RefCounter
    122  * This class implements implements a refernce counter which we can use
    123  * as a public base of objects managed by @CountedRefPtr.
    124  **/
    125 class RefCounter {
    126 
    127 public:
    128   /// Name numerical type for enumbering
    129   typedef short count_type;
    130 
    131   /// Allow our smart pointer to access internals
    132   template <class, bool, bool, class> friend class CountedRefPtr;
    133 
    134   /// Any Constructor resets the counter
    135   RefCounter(...): ref(0) {}
    136 
    137   /// Destructor
    138   ~RefCounter() { assume(ref == 0); }
    139 
    140 private:
    141   /// Number of references
    142   count_type ref;  // naming consistent with other classes
    143 };
    144 #endif
     24#include "blackbox.h"
     25#include "newstruct.h"
     26#include "ipshell.h"
     27
    14528class CountedRefEnv {
    14629  typedef CountedRefEnv self;
    14730
    14831public:
    149   static leftv idify(leftv head, idhdl* root) {
    150     idhdl handle = newid(head, root);
    151     leftv res = (leftv)omAlloc0(sizeof(*res));
    152     res->data =(void*) handle;
    153     res->rtyp = IDHDL;
    154     return res;
    155   }
    156 
    157   static idhdl newid(leftv head, idhdl* root) {
    158 
    159     static unsigned int counter = 0;
    160     char* name = (char*) omAlloc0(512);
    161     sprintf(name, " :%u:%p:_shared_: ", ++counter, head->data);
    162     if ((*root) == NULL )
    163       enterid(name, 0, head->rtyp, root, TRUE, FALSE);
    164     else
    165       *root = (*root)->set(name, 0, head->rtyp, TRUE);
    166 
    167     IDDATA(*root) = (char*) head->data;
    168     return *root;
    169   }
    170 
    171   static void clearid(idhdl handle, idhdl* root) {
    172     IDDATA(handle)=NULL;
    173     IDTYP(handle)=NONE;
    174     killhdl2(handle, root, NULL);
    175   }
     32
    17633  static int& ref_id() {
    17734    static int g_ref_id = 0;
     
    18542};
    18643
    187 #if 0
    18844/// Overloading ring destruction
    18945inline void CountedRefPtr_kill(ring r) { rKill(r); }
    190 class LeftvHelper {
    191 public:
    192   template <class Type>
    193   static Type* cpy(Type* result, Type* data)  {
    194     return (Type*)memcpy(result, data, sizeof(Type));
    195   }
    196   template <class Type>
    197   static Type* cpy(Type* data)  {
    198     return cpy((Type*)omAlloc0(sizeof(Type)), data);
    199   }
    200   template <class Type>
    201   static Type* recursivecpy(Type* data)  {
    202     if (data == NULL) return data;
    203     Type* result = cpy(data);
    204     result->next = recursivecpy(data->next);
    205     return result;
    206   }
    207   template <class Type>
    208   static Type* shallowcpy(Type* result, Type* data)  {
    209     cpy(result, data)->e = recursivecpy(data->e);
    210     return result;
    211   }
    212   template <class Type>
    213   static Type* shallowcpy(Type* data)  {
    214     return shallowcpy((Type*) omAlloc0(sizeof(Type)), data);
    215   }
    216   template <class Type>
    217   static void recursivekill(Type* current) {
    218     if(current == NULL) return;
    219     recursivekill(current->next);
    220     omFree(current);
    221   }
    222   static leftv allocate() { return (leftv)omAlloc0(sizeof(sleftv)); }
    223 
    224 };
    225 
    226 class LeftvShallow:
    227   public LeftvHelper {
    228   typedef LeftvShallow self;
    229  
    230 public:
    231   LeftvShallow(): m_data(allocate()) { }
    232   LeftvShallow(leftv data): m_data(shallowcpy(data)) { }
    233   LeftvShallow(const self& rhs):  m_data(shallowcpy(rhs.m_data)) { }
    234 
    235   ~LeftvShallow() { 
    236     recursivekill(m_data->e);
    237     omFree(m_data);
    238   }
    239   self& operator=(leftv rhs) {
    240     recursivekill(m_data->e);
    241     shallowcpy(m_data, rhs);
    242     return *this;
    243   }
    244 
    245   self& operator=(const self& rhs) { return (*this) = rhs.m_data; }
    246 
    247   /// Access to object
    248   const leftv operator->() const { return m_data;  }
    249   leftv operator->() { return m_data;  }
    250 
    251 protected:
    252   leftv m_data;
    253 };
    254 
    255 
    256 class LeftvDeep: public LeftvHelper {
    257   typedef LeftvDeep self;
    258 
    259   /// @name Do not permit copying
    260   //@{
    261   self& operator=(const self&);
    262   LeftvDeep(const self&);
    263   //@}
    264 
    265 public:
    266   struct copy_tag {};
    267   LeftvDeep(): m_data(allocate()) {}
    268   LeftvDeep(leftv data): m_data(cpy(data)) {
    269     data->e = NULL;   // occupy subexpression
    270     if(!isid()) m_data->data=data->CopyD();
    271   }
    272 
    273   LeftvDeep(leftv data, copy_tag): m_data(allocate()) {  m_data->Copy(data);  }
    274 
    275   ~LeftvDeep() { m_data->CleanUp(); }
    276   operator LeftvShallow() { return m_data;}
    277 
    278   bool like(const self& rhs) const { return m_data->data == rhs.m_data->data; }
    279 
    280   self& operator=(leftv rhs) {
    281     if(isid()) {
    282       m_data->e = rhs->e;
    283       rhs->e = NULL;
    284       IDTYP((idhdl)m_data->data) =  rhs->Typ();
    285       IDDATA((idhdl)m_data->data) = (char*) rhs->CopyD();
    286     }
    287     else {
    288       m_data->CleanUp();
    289       m_data->Copy(rhs);
    290     }
    291     return *this;
    292   }
    293 
    294   /// Check a given context for our identifier
    295   BOOLEAN brokenid(idhdl context) const {
    296     assume(isid());
    297     return (context == NULL) ||
    298       ((context != (idhdl) m_data->data) && brokenid(IDNEXT(context)));
    299   }
    300 
    301   /// Put a shallow copy to given @c leftv
    302   BOOLEAN put(leftv result) {
    303     leftv next = result->next;
    304     result->next = NULL;
    305     result->CleanUp();
    306 
    307     shallowcpy(result, m_data);
    308     result->next = next;
    309     return FALSE;
    310   }
    311 
    312   /// Get additional data (e.g. subexpression data) from likewise instances
    313   BOOLEAN retrieve(leftv res) {
    314     if (res->data == m_data->data)  {
    315       if(m_data->e != res->e) recursivekill(m_data->e);
    316       cpy(m_data, res);
    317       res->Init();
    318       return TRUE;
    319     }
    320     return FALSE;
    321   }
    322 
    323 
    324 
    325   BOOLEAN isid() const { return m_data->rtyp==IDHDL;}
    326   BOOLEAN ringed() { return m_data->RingDependend(); }
    327   BOOLEAN unassigned() const { return m_data->Typ()==0; }
    328 
    329   leftv idify(idhdl* root) {
    330     leftv res = (isid()? m_data: CountedRefEnv::idify(m_data, root));
    331     ++(((idhdl)res->data)->ref);
    332     return res;
    333   }
    334 
    335 
    336   void clearid(idhdl* root) {
    337     assume(isid());
    338     if (--((idhdl)m_data->data)->ref <= 0)  // clear only if we own
    339       CountedRefEnv::clearid((idhdl)m_data->data, root);
    340   }
    341 
    342 private:
    343   leftv m_data;
    344 };
    345 #endif
     46
     47
    34648/** @class CountedRefData
    34749 * This class stores a reference counter as well as a Singular interpreter object.
    348  *
    349  * It also stores the Singular token number, once per type.
     50 * It also take care of the context, e.g. the current ring, indexed object, etc.
    35051 **/
    35152class CountedRefData:
    35253  public RefCounter {
    35354  typedef CountedRefData self;
     55public:
    35456  typedef CountedRefWeakPtr<self*> back_ptr;
     57private:
    35558  typedef RefCounter base;
    35659
     
    758461  CountedRefShared(const base& rhs):  base(rhs) { }
    759462
    760   /// Genreate   
     463  /// Generate from data pointer
    761464  CountedRefShared(data_ptr rhs):  base(rhs) { }
    762465
     
    787490  /// Temporarily wrap with identifier for '[' and '.' operation
    788491  self subscripted() { return self(m_data->subscripted()); }
     492
     493  ///
     494  data_type::back_ptr weakref() { return m_data->weakref(); }
    789495
    790496  BOOLEAN retrieve(leftv res, int typ) {
     
    897603}
    898604
     605
     606BOOLEAN countedref_serialize(blackbox *b, void *d, si_link f)
     607{
     608  sleftv l;
     609  memset(&l,0,sizeof(l));
     610  l.rtyp = STRING_CMD;
     611  l.data = (void*)omStrDup("shared"); // references are converted
     612  f->m->Write(f, &l);
     613  CountedRefShared::cast(d).dereference(&l);
     614  f->m->Write(f, &l);
     615  return FALSE;
     616}
     617
     618BOOLEAN countedref_deserialize(blackbox **b, void **d, si_link f)
     619{
     620  // rtyp must be set correctly (to the blackbox id) by routine calling
     621  leftv data=f->m->Read(f);
     622  CountedRefShared sh(data);
     623  *d = sh.outcast();
     624  return FALSE;
     625}
     626
    899627void countedref_init()
    900628{
     
    910638  bbx->blackbox_Op3     = countedref_Op3;
    911639  bbx->blackbox_OpM     = countedref_OpM;
     640  bbx->blackbox_serialize   = countedref_serialize;
     641  bbx->blackbox_deserialize = countedref_deserialize;
    912642  bbx->data             = omAlloc0(newstruct_desc_size());
    913643  CountedRefEnv::ref_id()=setBlackboxStuff(bbx, "reference");
  • Singular/countedref.h

    re318c0 rcda275f  
    2020#ifndef SINGULAR_COUNTEDREF_H_
    2121#define SINGULAR_COUNTEDREF_H_
     22
     23#include <omalloc/omalloc.h>
     24#include <kernel/structs.h>
     25#include <kernel/febase.h>
    2226
    2327/** @class CountedRefPtr
     
    101105};
    102106
    103 /// Default constructor only implemented if @c NeverNull is false
    104 //template <class PtrType, bool isWeak,bool val,class CountType>
    105 //inline CountedRefPtr<PtrType, isWeak, val, CountType>::CountedRefPtr():
    106 //  m_ptr(NULL) { }
    107 
    108107/** @class RefCounter
    109108 * This class implements implements a refernce counter which we can use
     
    139138public:
    140139  friend class CountedRefWeakPtr<PtrType>;
     140  ~CountedRefIndirectPtr()  { }
     141
    141142private:
    142143  CountedRefIndirectPtr(PtrType ptr): m_ptr(ptr) { }
    143144  CountedRefIndirectPtr& operator=(PtrType ptr) { m_ptr = ptr; return *this; }
     145
    144146  PtrType m_ptr;
    145147};
     
    177179  /// Test whether reference was never used
    178180  bool unassigned() const { return !m_indirect; }
    179 
    180181  /// Pointer-style interface
    181182  //@{
    182183  operator bool() const {  return operator->(); }
    183184  self& operator=(const self& rhs) {
    184     m_indirect = rhs;
     185    m_indirect = rhs.m_indirect;
    185186    return *this;
    186187  }
     
    192193    return *this;
    193194  }
    194   bool operator==(ptr_type ptr) const { 
    195     return m_indirect &&(m_indirect->m_ptr == ptr); 
     195  bool operator==(ptr_type ptr) const {
     196    return m_indirect &&(m_indirect->m_ptr == ptr);
    196197  }
    197198  bool operator!=(ptr_type rhs) const { return !operator==(rhs); }
     
    199200  ptr_type operator->() {   return (m_indirect? m_indirect->m_ptr:NULL); }
    200201  //@}
    201 
    202202private:
    203203  ptrptr_type m_indirect;
    204204};
    205 
    206205
    207206
     
    275274};
    276275
     276/** @class LeftvShallow
     277 * Ths class wraps @c leftv by taking into acount memory allocation, destruction
     278 * as well as shallowly copying of a given @c leftv, i.e. we just copy auxiliary
     279 * information (like subexpressions), but not the actual data.
     280 *
     281 * @note This is useful to avoid invalidating @c leftv while operating on th
     282 **/
    277283class LeftvShallow:
    278284  public LeftvHelper {
     
    280286 
    281287public:
     288  /// Just allocate (all-zero) @c leftv
    282289  LeftvShallow(): m_data(allocate()) { }
     290  /// Shallow copy the input data
    283291  LeftvShallow(leftv data): m_data(shallowcpy(data)) { }
     292  /// Construct (shallow) copy of @c *this
    284293  LeftvShallow(const self& rhs):  m_data(shallowcpy(rhs.m_data)) { }
    285294
     295  /// Destruct
    286296  ~LeftvShallow() { 
    287297    recursivekill(m_data->e);
    288298    omFree(m_data);
    289299  }
     300
     301  /// Assign shallow copy of the input
    290302  self& operator=(leftv rhs) {
    291303    recursivekill(m_data->e);
     
    293305    return *this;
    294306  }
    295 
     307  /// Assign (shallow) copy of @c *this
    296308  self& operator=(const self& rhs) { return (*this) = rhs.m_data; }
    297309
    298   /// Access to object
     310  /// @name Pointer-style access
     311  //@{
    299312  const leftv operator->() const { return m_data;  }
    300313  leftv operator->() { return m_data;  }
     314  //@]
    301315
    302316protected:
     317  /// The actual data pointer
    303318  leftv m_data;
    304319};
    305320
    306 
    307 class LeftvDeep: public LeftvHelper {
     321/** @class LeftvDeep
     322 * This class wraps @c leftv by taking into acount memory allocation, destruction
     323 * as well as deeply copying of a given @c leftv, i.e. we also take over
     324 * ownership of the @c leftv data.
     325 *
     326 * We have two variants:
     327   + LeftvDeep(leftv):           treats referenced identifiers as "the data"
     328   + LeftvDeep(leftv, copy_tag): takes care of a full copy of identifier's data
     329 *
     330 * @note It invalidats @c leftv on input.
     331 **/
     332class LeftvDeep:
     333  public LeftvHelper {
    308334  typedef LeftvDeep self;
    309335
    310   /// @name Do not permit copying
     336  /// @name Do not permit copying (avoid inconsistence)
    311337  //@{
    312338  self& operator=(const self&);
     
    315341
    316342public:
    317   struct copy_tag {};
     343  /// Allocate all-zero object by default
    318344  LeftvDeep(): m_data(allocate()) {}
     345
     346  /// Store a deep copy of the data
     347  /// @ note Occupies the provided @c leftv and invalidates the latter
    319348  LeftvDeep(leftv data): m_data(cpy(data)) {
    320349    data->e = NULL;   // occupy subexpression
     
    322351  }
    323352
     353  /// Construct even deeper copy:
     354  /// Skip identifier (if any) and take care of the data on our own
     355  struct copy_tag {};
    324356  LeftvDeep(leftv data, copy_tag): m_data(allocate()) {  m_data->Copy(data);  }
    325357
     358  /// Really clear data
    326359  ~LeftvDeep() { m_data->CleanUp(); }
    327   operator LeftvShallow() { return m_data;}
    328 
     360
     361  /// @name Access via shallow copy to avoid invalidating the stored handle
     362  //@{
     363  operator LeftvShallow() { return m_data; }
     364  LeftvShallow operator*() {return *this; }
     365  //@}
     366
     367  /// Determine whether we point to the same data
    329368  bool like(const self& rhs) const { return m_data->data == rhs.m_data->data; }
    330369
     370  /// Reassign a new deep copy by occupieing another @c leftv
     371  /// @note clears @c *this in the first
    331372  self& operator=(leftv rhs) {
    332373    if(isid()) {
     
    373414
    374415
    375 
     416  /// Check for being an identifier
    376417  BOOLEAN isid() const { return m_data->rtyp==IDHDL;}
     418  /// Test whether we reference to ring-dependent data
    377419  BOOLEAN ringed() { return m_data->RingDependend(); }
     420  /// Check whether (all-zero) initialized data was never assigned.
    378421  BOOLEAN unassigned() const { return m_data->Typ()==0; }
    379422
     423  /// Wrap data by identifier, if not done yet
    380424  leftv idify(idhdl* root) {
    381425    leftv res = (isid()? m_data: LeftvHelper::idify(m_data, root));
     
    384428  }
    385429
    386 
     430  /// Erase identifier handles by @c *this
     431  /// @note Assumes that we reference an identifier and that we own the latter.
     432  /// This is useful to clear the result of a subsequent call of @c idify.
    387433  void clearid(idhdl* root) {
    388434    assume(isid());
     
    392438
    393439private:
     440  /// Store the actual data
    394441  leftv m_data;
    395442};
Note: See TracChangeset for help on using the changeset viewer.