The following releases were made on the original pavkam/DeHL repo. Releases were not dated.
- Fixed a problem in Tuple<T1, T2, T3, T4> in variant conversion (from variant would fail).
- Fixed TDictionary.Create. It ignored the InitialCapacity parameter. (thanks to Mason Wheeler)
- Fixed a bug in BigInteger and BigCardinal when converting a Variant (containing those types) to an AnsiString.
- Fixed a memory leak in TConverter (DeHL.Conversion). The static destructor did not free the mapping dictionary. (Thanks to Tim Kelly for providing a test case).
- Fixed a memory leak caused by TSuppressedWrapperType. It reported tmManual even for tmCompiler types. This resulted in some collections doing optimizations and forgetting to "clean" the values. (Thanks to Tim Kelly for providing a test case).
- Any IType can now be converted to IComparer and IEqualityComparer (from Generics.Collections) by calling IType.AsComparer and IType.AsEqualityComparer methods. This functionality is useful if you want to use DeHL's type objects in RTL's Generics.Collections.
- TType now caches the types in the local instantiated types and does not use any internal interface list for this purpose. This fixes a bug related to DeHL used as a runtime package, plus, it is faster now. (Again, thanks to Mason Wheeler for a valid test case)
- New type wrapper: TMaybeObjectWrapperType used in collections that "might" work on objects and need to control object's life-time.
- Serializers now expose a InReadableForm property that can be accessed while serializing. Types can decide whether to serialize "in human readable form" or in a more optimized form (depend on type of course). This change is useful for custom types mostly.
- TString can now implicitly convert to and from a variant.
- TFixedArray and TDynamicArray are now enumerable. &Array can now generate an enumerator object for any TArray.
- New unit DeHL.Bytes. Currently contains a single type TBuffer. TBuffer is a wrapper around RawByteString and provides a lot of functions for simplified byte buffer manipulations.
- &Array. Sort now can accept a sorting anonymous method for sorting.
- New implementation of Scoped.
- Two new "auto_ptr" classes: Shared and Weak. Shared holds a "strong" reference to an object while Weak holds a "weak" reference. You can obtain weak references from "strong" but there is a change that you cannot obtain a "strong" reference from a "weak" one. If the last "strong" reference is lost, the managed object is destroyed and all "weak" references won't be able to obtain a "strong" reference back.
- Renamed DeHL.Scoped to DeHL.References.
- Optimized BigCardinal's NEG operator. It won't raise an exception if Q+ is enabled.
- New data type -- Half. Half is basically "half of a Single". It is a floating point type with much smaller precision but necessary in some particular circumstances (see IEEE 754-2008 spec). Implementation uses super-fast conversion tables (from and to Single).
- BigInteger and BigCadinal now make sure to serialize based on serializer's InReadableForm property.
- New data type -- BigDecimal. Used Java's BigDecimal to model the API of the type. BigDecimal offers fixed "infinite" precision floating point calculus.
- BigCardinal now offers IsZero, IsEven, IsOdd properties. Added TryParse, Parse, ToString, Abs, Pow and DivideAndRemainder methods. Removed Abs, UIntToStr and StrToBigCardinal routines (replaced by statics on BigCardinal). Also BigCardinal now offers Zero, One and Ten properties.
- BigInteger now offers IsZero, IsPositive, IsNegative, IsEven, IsOdd properties. Added TryParse, Parse, ToString, Abs, Pow and DivideAndRemainder methods. Removed Abs, IntToStr and StrToBigInteger routines (replaced by statics on BigInteger). Also BigInteger now offers Zero, One, MinusOne, Ten and MinusTen properties. BigInteger can now be shifted left and right. Optimized the creation with some factory details.
- Moved the IEnumerable and IEnumerator from DeHL.Collections.Base to DeHL.Base.
- All object variants of associative collections (ex. TObjectDictionary or TObjectMultiMap) do not restrict the type parameters to class. This means that you can now declare a TObjectDictionary<string, TObject>.
- TList.Sort now can accept a sorting anonymous method that overrides the default comparison function (IType's).
- IEnexCollection.Sorted now can accept a sorting anonymous method that overrides the default comparison function (IType's).
- DeHL.Converter was renamed to DeHL.Conversion. The old TConverter class was completely rewritten. The most used convertions are now done directly in the class (and not through Variants). Support for converting classes to classes, interfaces and etc was added. Custom convertions can be plugged in.
- New DeHL.Tuples unit. Contains Tuple, Tuple<T1, T2> .... for 7 types. A non-generic Tuple that can be used to simplify tuple creation. A new specialized Tuple type called KVPair<TKey, TValue>.
- Completed transition to NativeInts all over DeHL.
- DeHL.KeyValuePair has been removed. TKeyValuePair<TKey, TValue> has beed replaced with KVPair<TKey, TValue> in DeHL.Tuples.
- All collections now use KVPair from DeHL.Tuples instead of TKeyValuePair.
- Removed TBinaryTree from the library. It was buggy, poorly tested and utterly ... well ... unuseful.
- Added a new unit DeHL.Strings that contains a single type: TString. TString is a somewhat .NET compatible string. It wraps around Delphi strings and provides a nice OOP-ish flavour to it.
- Fixed an Access Violation in TDynamicArray.Remove and RemoveAndShrink.
- Fixed two function declarations (while definitions were different). The compiler seemed to silently accept those for some reason.
- Implemented a new ENEX operation: Cast. Usage: Collection.Op.Cast. This operation will check and select certain objects from a collection.
- Use NativeInt and NativeUInt instead of Integer and Cardinal in core places. Replaced Pointer -> Integer cast to use NativeInt instead. This makes the core of DeHL more 64bit friendly.
- New DeHL.Cloning unit that is home for TReplicator class. It also declares ICloneable interface. Combined together these two provide an easy way to deep or shallow clone any type (not just objects).
- Fixed a few messages to be clear about minimum supported Delphi version (also uses {$MESSAGE} now).
- Moved TPointerDictionary out of TType class and into DeHL.Base unit. It's useful in more places that require a dictionary and do not need to reference the whole Enex (collections).
- Fixed a small number of bugs in TType. Added tests to ensure that never happens again.
- Remove a number of type registration since the RTL/Compiler would take care of those anyway.
- AreEqual is no longer a virtual method and cannot be overridden in descendent classes. AreEqual now simply calls Compare. This change was made to avoid further confusions.
- New TWrapperType which is the base for the rest of wrappers and serves as base for TComparerWrapperType.
- TType.Default and Standard now have 2 more overloads each accepting comparator and hasher anonymous methods (uses TComparerWrapperType as wrapper). You can now get the type object you wanted but with overridden comparison rules.
- Support for metaclass serialization. Extended core serialization to allow metaclasses. Each serializer engine can store them as they like (currently as fully-qualified names).
- Fixed a problem in the serializer core. Classes that defined a field that had the same name as an inherited field would fail to serialize properly. Not each duplicated field gets an unique name depending on the ancestor.
- By request, unsealed all "Object" collection flavours (for example TObjectDictionary).
- Removed Delphi 2009 support. Cleaned up the Defines.inc file and the source code. The removal of 2009 was necessary due to high amount of Generics bugs and ever-increasing differences in RTTI support. Version 0.7 still supports both 2009 and 2010 versions.
- Implemented CharInSet routine for (TWideCharSet) DeHL.WideCharSet so that existing code could be updated in a simple fashion (from ANSI sets to WIDE sets).
- TDynamicArray and TFixedArray now support Insert, Append and ExtendAndInsert that accept arrays instead of just single items.
- Since support for 2009 was dropped. Almost all instances of "array of" were replaced with TArray.
- Implemented Activator class (in DeHL.Base). It declares 4 static methods that can be used to create an instance of a class (using RTTI to find the first parameterless contructor). Activator is used by the serialization engine.
- IFDEF-ed a bit of code related to how Rtti unit handles dynamic array's element type.
- Fixed a bug in TIntegerType.Compare. "Subtraction" was used there, which provided wrong results in some cases.
- Dynamic arrays can now be converted to Variants (and back).
- Dynamic array type crashed for "nil" arrays. It's fixed now.
- Implemented new TRecordType to support 2010 records (all records by default have RTTI). The old TBinaryRTTIType has been killed since it was a hack for 2009 basically.
- Implemented TPointerType that serves all pointers.
- Implemented TArrayType that serves static arrays.
- Implemented TMetaclassType for class ref support.
- Implemented TInterfaceType for proper interface handling (ref counting and all).
- Implemented TMethodType for proper method support. Cannot use Binary type for it since the calling convention plays it role here.
- Implemented TProcedureType for procedure support.
- Remove from registered list. Double will take care of it anyway.
- Type support classes exteded to support Serialize and Deserialize methods. Each type implements its own serialization mechanism.
- TType was extended with serialization utilities and properly serves its purpose.
- TDynamicArray and TFixedArray now provide their own TTypes
- Implemented a new collection: T(Object)Heap (in DeHL.Collections.Heap). THeap provides an unordered "heap" of values. You put in a value into the heap and obtain an ID that can later be used to retrieve that value. This class is useful in some circumstances when you would not care about any king of ordering.
- TEnexCollection implements ISerializable now. Also both Enex and associative enex collections can serialize and deserialize themselves. There are a few collections that cannot serialize/deserialize out there though.
- New units:
- DeHL.Serialization -- provides basic definitions for ISerializationContext, IDeserializationContext, TSerializationData, TDeserializationData, TValueInfo, ISerializable and IDeserializationCallback.
- DeHL.Serialization.Abstract -- Implements an abstract class to be used as base for other specific serializers. Classes provided: TAbstractSerializationContext<...> and TSerializer<...>.
- DeHL.Serialization.Xml -- Provides an XML serialization engine based on TXMLDocument and IXMLNode. Supports XmlName, XmlElement, XmlAttribute, XmlNullable and XmlArrayElement attributes.
- DeHL.Serialization.Ini -- Provides an Ini serialization engine based on TCustomIniFile. Can work with all descendents (including TMemInifile and TRegIniFile). Supports IniName and IniArrayElement attributes.
- DeHL.Serialization.Binary -- Provides a fast TStream-based binary serialization engine.
- By default some types cannot be serialized (such as Variant, interface, opaque pointers, etc). Use [NonSerializable] attribute to skip the fields you don't want/or can't be serialized.
- All DeHL types were extended to support serialization (including TKeyValuePair, Nullable, WideCharSet, BigCardinal, BigInteger, TDynamicArray, TFixedArray, TBox, etc)
- Implement ISerializable interface in your classes to provide custom serialization. Note that the interface methods will be called "with no modification to ref count".
- Implement IDeserializedCallback to provided a method that will get called when the class is fully deserialized.
- Pointer types that point to records also serialize those records.
- Added a global DeHL.Defines.inc file to store all pre-processor stuff. Currently it contains DCC32 issue related defines and selectively enables features based on their status on D2009 and D2010.
- A non-recursive QuickSort implementation. It is controlled by a switch in DeHL.Defines.inc and is enabled by default (Thanks to Dmitry Atamanov).
- [2010] Singleton<> class. Uses class constructors to create an instance of the class. Singleton.Instance will always return the same instance in all units in the application.
- TWideCharSet type has been added. A record type with overloaded operators.
- Overloaded operators for any case to make it look and feel like normal language sets.
- Uses a combination of dynamic arrays and TSysCharSets internally.
- Can be converted to IEnexCollection for each operating upon.
- Support enumerability.
- TConverter class moved out to its own unit.
- TFixedArray and TDynamicArray support ToVariantArray() method. You can easily convert a normal array to a variant array.
- DeHL.Types now implements a custom TDictionary (only visible internally).
- This results in un-linking ALL Enex code from the application.
- The internal dictionary does not rely on TType system making it behave well in pre-initialization mode.
- Compile times are smaller for simple programs.
- All cached instances of TType classes are freed upon program termination. This should avoid popping up "memory leaks" dialogs.
- TType<> now exposes IsRegistered method that returns a Boolean value indicating whether a custom type class was registered for a given class: e.g. TType.IsRegistered.
- Array support type objects now transform the arrays into Variant arrays (and back!). Modified the declaration of the TDynArrayType to support that.
- [D2010] TKeyValuePair is now type-supported.
- For each type instantiation the class constructor registers a type support class.
- If the pair contains cleanable items these are cleaned up by the pair.
- If converted to variant, a variant array of 2 is created foe key and value (back too!).
- Delphi 2009 users must register a TKeyValuePairType<> instance for each instantiation of the pair.
- [D2010] Scoped<> type now registers custom type classes for each specialization.
- All type support code is tunneled to the enclosed type.
- Delphi 2009 users will have to manually instantiate and supply TScopedType instances.
- [D2010] Nullable<> type now registers custom type classes for each specialization.
- All type support code is tunneled to the enclosed type.
- Delphi 2009 users will have to manually instantiate and supply TNullableType instances.
- The last legacy portions of Enex separation are removed:
- GetType, GetKeyType and GetValueType protected methods are no more. Other means are used to store type objects.
- AdjustType, AdjustKeyType and AdjustValueType were removed and InstallType(s) were added.
- All classes were updated to use the new simplified model, and some long-forgot parameter names were renamed properly.
- Moved Cast<>() and Select<>() methods to a new location. Now all Enex interfaces expose a new routine "Op".
- Example: List.Op.Cast(); Since Op returns a record types, you can use generic methods in it.
- This allows for more powerful stuff to be written, for example GroupBy and alike.
- DistinctByKeys() and DistinctByValues() methods added for associative Enex collections.
- ToDictionary(), ToList() and ToSet() were added to the Enex interfaces. For example, you can write: SomeDict.SelectKeys.ToList() to obtain all the keys in a dictionary in a list.
- Sorted() and Reversed() for non-associative collections. For example: SomeList.Sorted().ToList() will give you another list which has the contents of the first one but sorted.
- New unit DeHL.Collections.Abstract was added. It contains base classes for MultiMaps, BidiMaps, DistinctMultiMaps and Bags. Since most of the code is shared between normal, sorted and double-sorted versions it made sense. MultiMaps, DistinctMultiMaps and BidiMaps store the values either in lists or sets.
- Fixed a potential problem in Hash-based classes. It was processing all entries even those that did not have valid items in them.
- TBidiMap, TSortedBidiMap and TDoubleSortedBidiMap classes are now implemented.
- TBidiMap is a bi-directional map in which for each Key there is one or more distinct values and for each Value there is one or more distinct Keys.
- TSortedBidiMap and TDoubleSortedBidiMap impose sorting on Keys and Values.
- TDistinctMultiMap, TSortedDistinctMultiMap and TDoubleSortedDistinctMultiMap classes now provide a specialized version of TMultiMap
- The elements in the map are stored in sets and not lists (as in TMultiMap and alike).
- Supports sorting on keys and on values.
- New collection class: TPriorityQueue<TPriority, TValue>.
- It does not implement the normal Queue interfaces since it is an associative collection.
- TPriority is used as priority measure (must support comparing).
- Interoperability classes (for normal VCL): TStringList and TWideStringList derive from the normal TStringList and TWideString list but add a generic layer on top. The values are stored in TBox<>es inside the Objects[] property.
- Make DeHL compile on Tiburon!
- Massive optimizations in type support routines:
- Moved all statics from TType to TType. This makes sure that those methods are not instantiated all over the place.
- Moved variables around from TType to TType to make more sense.
- Use caching to store the generated IType-s. Using Interlocked* routines to make sure caching is thread safe. Make sure that caches are cleared upon custom registration of types.
- Add more precise points to prime numbers, and rename a function for a better explanation of its purpose.
v0.5 was skipped
- Since people are using different versions of Delphi 2009 and 2010, I have decided to provide a special place where you can toggle certain options to check whether a specific feature may work on your compiler. Check out the DeHL.Base unit. It contains a set of TOGGLE_.... constants at the beginning.
- Since the Weaver builds introduced extended RTTI (pointers and class references for example now have RTTI), DeHL has been adjusted to support that.
- Merged DeHL.Collections.Interfaces with DeHL.Collections.Enex into DeHL.Collections.Base unit.
- Disposed of the DeHL.Collections.Utils hack-unit.
- New DeHL.Math.Primes unit, dedicated only to the prime numbers.
- Merged DeHL.Collections.FixedArray with DeHL.Collections.DynamicArray into DeHL.Arrays.
- Moved some units to Extensions/ directory.
- Internal cleanup, getting rid of all intermediate levels of development, moving into the future.
- Fixed an issue regarding NativeInt, NativeUInt and Char registrations.
- Make sure everything works as expected with Range checks enabled.
- Introduced the concept of type extender and type extension. Using the type extenders, you can associate type extensions with certain types. This model is used by the Math extensions to provide math functions to all types supporting it.
- Mathematical type extensions in DeHL.Math.Types unit. You can use the provided classes to obtain math type extension classes that can be used to perform math operations on the generic types.
- Custom math types can now register into the math extension mechanisms. BigCardinal and BigInteger do exactly that.
- New type TBox. This type allows transparent boxing of any non-object value inside an object:
- Implements IBox, IBox and extends TBox class.
- Implements IComparable and IEquatable interfaces from System.pas.
- Forwards all it's type info to the held value.
- Always in a predictable state (has value, doesn't have a value).
- If you register a type support class for your object type, then, it will be used for all types descending from the one you have registered. For example, registering a type support for TPersistent ensures that all objects deriving from TPersistent will be receiving the registered type support (unless a specific one is registered).
- IEnexEnumerable is no more! There are new interfaces and types in DeHL.Collections.Base:
- ICollection: IEnumerable, contains basic operations on all collections.
- IEnexCollection: ICollection, contains the methods from the old IEnexEnumerable.
- IEnexAssociativeCollection: ICollection, supports methods specific to associative collections.
- TCollection, TEnexCollection and TEnexAssociativeCollection base classes.
- TEnumerator base class used for all enumerators in DeHL.
- Enex is now built-in. It is no longer an option!
- CopyTo methods are now a part of ICollection/TCollection so that all collections can take advantage of a default implementation based on enumerators.
- ToArray (only for newer Weaver builds), ToFixedArray and ToDynamicArray methods are now exposed by ICollection.
- IEnexAssociativeCollection provides LINQ-like extensions for associative collections. All types supporting this functionality have been extended to allow optimized access.
- A new large number of generic collections:
- TLinkedStack, a stack implementation based on linked lists.
- TLinkedQueue, a queue implementation based on linked lists.
- TSortedDictionary<TKey, TValue>, a dictionary implementation based on AVL trees.
- TSortedSet, a set implementation based on AVL trees.
- TSortedBag, a bag implementation based on TSortedDictionary<TKey, TValue> (aka AVL trees).
- TSortedMultiMap<TKey, TValue>, a multi-map implementation based on TSortedDictionary<TKey, TValue> (aka AVL trees).
- TDoubleSortedMultiMap<TKey, TValue>, a multi-map implementation based on TSortedDictionary<TKey, TValue> (aka AVL trees).
- Removed Sum and Average from the IEnexCollection. These methods have been moved to a separate static class.
- DeHL.Math.Algorithms introduces a nice way to perform Sum and Average on collections created over arithmetic types. Accumulator.Sum and Accumulator.Average are your friends now.
- IEnexCollection now has a new method: AggregateOrDefault. It was necessary to avoid multiple operations in certain scenarios.
- All collection classes are now able to be created from a TFixedArray or TDynamicArray.
- TLinkedList got two new methods: RemoveAndReturnFirst and RemoveAndReturnLast. These two were necessary since there was no method to retrieve an element without cleaning it up.
- A large number of generic interfaces implemented by all classes:
- IStack, implemented by TStack and TLinkedStack.
- IQueue, implemented by TQueue and TLinkedQueue.
- ISet, implemented by TArraySet, THashSet and TSortedSet.
- IDictionary<TKey, TValue>, implemented by TDictionary<TKey, TValue> and TSortedDictionary<TKey, TValue>.
- IMultiMap<TKey, TValue>, implemented by TMultiMap<TKey, TValue>, TSortedMultiMap<TKey, TValue> and TDoubleSortedMultiMap<TKey, TValue>.
- IList, implemented by TList and TSortedList.
- IBag, implemented by TBag and TSortedBag.
- All Enex collections and enumerators now keep interface references of each other to keep the chain alive even for enumerator-but-no-enumerable chains.
- In order to provide more Delphi compatibility it was decided to provide object versions of all collections. Although this concept directly opposes the notion of decoupled types-collections, a simulated support was added. All types now have object variants, prefixed with "Object" (aka TObjectList, TObjectDictionary). All expose the OwnsObjects, OwnsKeys, OwnsValues properties.
- And finally, a new logo :)
- Enex support. A base set of interfaces that allow Linq-like queries on all collections
- Some problems in the compiler prevent the use of generic function Select and Cast for now.nThese two could have been used to transform each element of the collection to some other type.
- Everything is based in interfaces to make use of automatical garbage collection. the only restriction is that the first enumerable (from which the chain starts) should be either an interface or must be destroyed explicitly.
- All collections have overriden versions of some functions. For example in a list, the First() method is implemeted directly so that you benefit from full speed whenever possible.
- No lambdas - that makes writing selectors or predicates rather unpleasant.
- Sum() and Average() are only supported for types registered as integers or reals (including BigCardinal and BigInteger).
- All selector and predicate-based selection is done on-the fly so there is no additional memory used!
- Type support classes now expose methods to convert a type from an to a Variant.
- Based on the newly added Variant conversion, a new type: TConverter<T1, T2> is present. You can use it to support "blind" conversion in a class.
- Much improved type support system:
- Now more functionality is split between generic and non-generic variants of the type support classes (IType, IType, TType, TType).
- TypeSupport has been renamed to TType and IType repectively.
- IType/TType now export Name, Size, Management, TypeInfo and Family properties. You can use those properties to get more information about your generic type.
- Custom type registration has been improved. A new cleaner API can be used to register you custom types into the DeHL's type system.
- TType.Default is now an overloaded function. The first form is the usual one. The second form receives a set of "type families" that are expected to represent the generic type. This way you can effectively impose run-time type restrictions.
- TClassType is now generic with T being class-restricted. This allows to avoid compile-time type incompatibilities.
- All important standard types in Delphi are now supported. This support required the working custom types system, since these types can't be handled by default:
- Boolean, ByteBool, WordBool, LongBool
- TDateTime, TTime, TDate
- NativeInt, NativeUInt
- Real
- OleVariant
- UCS4Char, UCS4String
- UTF8String
- RawByteString
- Fixed a bug in BigCardinal related to zero-length numbers
- BigCardinals embedded in variants now properly negate.
- Support for the NOT operation for BigCardinal.
- As usual, some tests.
- Renamed the library to DeHL in hopes to remove the length of the unit names.
- Renamed all classes to use the T prefix rather than H. It was an unfamiliar mode of naming things.
- BigCardinal and BigInteger can be used within a Variant type. An implicit operator is declared to allow seamlessly to convert from the BigInteger/Cardinal to Variants.
- Type Support has been extended to offer better information about the clean-up practices of a type.
- Added methods to move a number of elements from an array safely (for ref-counted Delphi types). Also fixed the code to use these methods instead of Move directly.
- Added a new array type: TFixedArray. It is an immutable array which is used only for reading. TDynamicArray can be created off TFixedArrays.
- Added work-around fixes for a few Delphi bugs blocking the compilation.
- The testing module was cleaned up a bit. Now using a base class for all our test cases. Also tests for new scenarios have been added.
- All container classes now cleanup their contained values (when required). This means it is now safe to use them with types that require cleanup.
- Cleaned up the binary tree implementation a bit and fixed a bug.
- Externalized the last remaining hard-coded strings in the code.
- Improved the performance for IntToStr functions for 'big numbers'. (From 25 minutes to 17 seconds for a 256^10000 number). A BCD-izer algorithm was used to create a BCD version of the BigCardinal and to apply a simple 4-bit digit to char translation.
- The same was done for IntToHex.
- Small numbers use the RTL provided IntToStr and IntToHex routines.
- Added the last missing piece of the Collections pack: HMultiMap.
- And a number of other changes.
- Improved date and time manipulation. All packed nicely in records with overloaded operators and utility functions.
- Big numbers. The library includes support for BigInteger and BigCardinal data-types. Both types have overloaded operators, utility functions and etc goodness.
- "Type Support". My equivalent to Generics.Defaults present in Delphi. I've chose to go my way because of the style the Generics.Defaults is written in and mostly because my version is extensible and supports more options.
- All code is unit-tested to avoid most bugs.
- First public version!
- Date and Time utilities are added (HDate, HTime, HDateTime and HTimeSpan)
- HLinkedList, HStack, HQueue, HList, HDictionary, HArraySet, HSortedList, HBinaryTree collections are implemented.
- SmartPointers unit is added (later - Scoped).
- The TypeSupport concept is implemented.
- DynamicArray type is implemented.