@@ -794,6 +794,28 @@ pub unsafe trait Alloc {
794
794
. map ( |p| Excess ( p, usable_size. 1 ) )
795
795
}
796
796
797
+ /// Behaves like `alloc`, but also ensures that the contents are set to zero
798
+ /// before being returned. For some `layout` inputs, like arrays, this may
799
+ /// include extra storage usable for additional data.
800
+ ///
801
+ /// # Safety
802
+ ///
803
+ /// This function is unsafe for the same reasons that `alloc` is.
804
+ ///
805
+ /// # Errors
806
+ ///
807
+ /// Returning `Err` indicates that either memory is exhausted or
808
+ /// `layout` does not meet allocator's size or alignment
809
+ /// constraints, just as in `alloc`.
810
+ ///
811
+ /// Clients wishing to abort computation in response to an
812
+ /// allocation error are encouraged to call the allocator's `oom`
813
+ /// method, rather than directly invoking `panic!` or similar.
814
+ unsafe fn alloc_zeroed_excess ( & mut self , layout : Layout ) -> Result < Excess , AllocErr > {
815
+ let usable_size = self . usable_size ( & layout) ;
816
+ self . alloc_zeroed ( layout) . map ( |p| Excess ( p, usable_size. 1 ) )
817
+ }
818
+
797
819
/// Attempts to extend the allocation referenced by `ptr` to fit `new_size`.
798
820
///
799
821
/// If this returns `Ok`, then the allocator has asserted that the
@@ -845,6 +867,60 @@ pub unsafe trait Alloc {
845
867
}
846
868
}
847
869
870
+ /// Attempts to extend the allocation referenced by `ptr` to fit `new_size`.
871
+ /// For some `layout` inputs, like arrays, this may include extra storage
872
+ /// usable for additional data.
873
+ ///
874
+ /// If this returns `Ok`, then the allocator has asserted that the
875
+ /// memory block referenced by `ptr` now fits `new_size`, and thus can
876
+ /// be used to carry data of a layout of that size and same alignment as
877
+ /// `layout`. (The allocator is allowed to
878
+ /// expend effort to accomplish this, such as extending the memory block to
879
+ /// include successor blocks, or virtual memory tricks.)
880
+ ///
881
+ /// Regardless of what this method returns, ownership of the
882
+ /// memory block referenced by `ptr` has not been transferred, and
883
+ /// the contents of the memory block are unaltered.
884
+ ///
885
+ /// # Safety
886
+ ///
887
+ /// This function is unsafe because undefined behavior can result
888
+ /// if the caller does not ensure all of the following:
889
+ ///
890
+ /// * `ptr` must be currently allocated via this allocator,
891
+ ///
892
+ /// * `layout` must *fit* the `ptr` (see above); note the
893
+ /// `new_size` argument need not fit it,
894
+ ///
895
+ /// * `new_size` must not be less than `layout.size()`,
896
+ ///
897
+ /// # Errors
898
+ ///
899
+ /// Returns `Err(CannotReallocInPlace)` when the allocator is
900
+ /// unable to assert that the memory block referenced by `ptr`
901
+ /// could fit `layout`.
902
+ ///
903
+ /// Note that one cannot pass `CannotReallocInPlace` to the `oom`
904
+ /// method; clients are expected either to be able to recover from
905
+ /// `grow_in_place` failures without aborting, or to fall back on
906
+ /// another reallocation method before resorting to an abort.
907
+ unsafe fn grow_in_place_excess ( & mut self ,
908
+ ptr : NonNull < Opaque > ,
909
+ layout : Layout ,
910
+ new_size : usize ) -> Result < Excess , CannotReallocInPlace > {
911
+ let _ = ptr; // this default implementation doesn't care about the actual address.
912
+ debug_assert ! ( new_size >= layout. size) ;
913
+ let ( _l, u) = self . usable_size ( & layout) ;
914
+ // _l <= layout.size() [guaranteed by usable_size()]
915
+ // layout.size() <= new_layout.size() [required by this method]
916
+ if new_size <= u {
917
+ return Ok ( Excess ( ptr, u) ) ;
918
+ } else {
919
+ return Err ( CannotReallocInPlace ) ;
920
+ }
921
+ }
922
+
923
+
848
924
/// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`.
849
925
///
850
926
/// If this returns `Ok`, then the allocator has asserted that the
@@ -900,6 +976,62 @@ pub unsafe trait Alloc {
900
976
}
901
977
}
902
978
979
+ /// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`.
980
+ /// For some `layout` inputs, like arrays, this may include extra storage
981
+ /// usable for additional data.
982
+ ///
983
+ /// If this returns `Ok`, then the allocator has asserted that the
984
+ /// memory block referenced by `ptr` now fits `new_size`, and
985
+ /// thus can only be used to carry data of that smaller
986
+ /// layout. (The allocator is allowed to take advantage of this,
987
+ /// carving off portions of the block for reuse elsewhere.) The
988
+ /// truncated contents of the block within the smaller layout are
989
+ /// unaltered, and ownership of block has not been transferred.
990
+ ///
991
+ /// If this returns `Err`, then the memory block is considered to
992
+ /// still represent the original (larger) `layout`. None of the
993
+ /// block has been carved off for reuse elsewhere, ownership of
994
+ /// the memory block has not been transferred, and the contents of
995
+ /// the memory block are unaltered.
996
+ ///
997
+ /// # Safety
998
+ ///
999
+ /// This function is unsafe because undefined behavior can result
1000
+ /// if the caller does not ensure all of the following:
1001
+ ///
1002
+ /// * `ptr` must be currently allocated via this allocator,
1003
+ ///
1004
+ /// * `layout` must *fit* the `ptr` (see above); note the
1005
+ /// `new_size` argument need not fit it,
1006
+ ///
1007
+ /// * `new_size` must not be greater than `layout.size()`
1008
+ /// (and must be greater than zero),
1009
+ ///
1010
+ /// # Errors
1011
+ ///
1012
+ /// Returns `Err(CannotReallocInPlace)` when the allocator is
1013
+ /// unable to assert that the memory block referenced by `ptr`
1014
+ /// could fit `layout`.
1015
+ ///
1016
+ /// Note that one cannot pass `CannotReallocInPlace` to the `oom`
1017
+ /// method; clients are expected either to be able to recover from
1018
+ /// `shrink_in_place` failures without aborting, or to fall back
1019
+ /// on another reallocation method before resorting to an abort.
1020
+ unsafe fn shrink_in_place_excess ( & mut self ,
1021
+ ptr : NonNull < Opaque > ,
1022
+ layout : Layout ,
1023
+ new_size : usize ) -> Result < Excess , CannotReallocInPlace > {
1024
+ let _ = ptr; // this default implementation doesn't care about the actual address.
1025
+ debug_assert ! ( new_size <= layout. size) ;
1026
+ let ( l, u) = self . usable_size ( & layout) ;
1027
+ // layout.size() <= _u [guaranteed by usable_size()]
1028
+ // new_layout.size() <= layout.size() [required by this method]
1029
+ if l <= new_size {
1030
+ return Ok ( Excess ( ptr, u) ) ;
1031
+ } else {
1032
+ return Err ( CannotReallocInPlace ) ;
1033
+ }
1034
+ }
903
1035
904
1036
// == COMMON USAGE PATTERNS ==
905
1037
// alloc_one, dealloc_one, alloc_array, realloc_array. dealloc_array
0 commit comments